Skip to content
← Wszystkie wpisy
4 min czytania Dawid Skłodowski

Rails 4.1: secrets.yml, podglądy mailerów, enumy i Spring

Rails 4.1 to po cichu znakomite wydanie punktowe. Przegląd funkcji, które wdrożyliśmy od razu — config/secrets.yml, podglądy ActionMailera, enumy ActiveRecord, preloader Spring i warianty żądań — wraz z drobnym drukiem każdej.

Rails 4.1 to rodzaj wydania, które nie robi nagłówków, a mimo to poprawia twoją codzienność bardziej niż te, które robią. Nie ma jednej sztandarowej funkcji; zamiast tego jest garść dobrze przemyślanych dodatków, z których każdy usuwa powracającą uciążliwość. Przenieśliśmy kilka aplikacji i wdrożyliśmy większość z nich w pierwszym tygodniu. Oto przegląd, z drobnym drukiem.

config/secrets.yml: jeden dom dla sekretów

Przez lata sekrety konfiguracyjne w Railsach były rozproszonym bałaganem — wartości wpisane na sztywno w inicjalizatorach, przemycane przez ENV albo zagrzebane w secret_token.rb. 4.1 wprowadza config/secrets.yml, jeden, świadomy środowiska dom dla nich:

# config/secrets.yml
development:
  secret_key_base: a_long_dev_key
  stripe_api_key: sk_test_xxx

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  stripe_api_key:  <%= ENV["STRIPE_API_KEY"] %>
Rails.application.secrets.stripe_api_key   # => wartość dla bieżącego środowiska

Wzorzec, który się wyłonił i którego się trzymamy, to najlepsze z obu światów: prawdziwe wartości dla developmentu i testu żyją w pliku, podczas gdy produkcja czyta z ENV przez interpolację ERB. To trzyma nazwy twoich sekretów w jednym udokumentowanym, wersjonowanym miejscu (nowy programista widzi, czego aplikacja potrzebuje), trzymając zarazem wartości produkcyjne poza repozytorium. Zauważ, że secret_key_base — klucz podpisujący twoje ciasteczka sesji — też teraz tu mieszka, zastępując stary secret_token.rb.

Jedno zastrzeżenie: cokolwiek z prawdziwą wartością w secrets.yml jest commitowane, więc trzymaj poświadczenia produkcyjne w ENV, nie w pliku. Plik dokumentuje kształt; środowisko dostarcza sekrety.

Podglądy ActionMailera: zobacz swoje maile w przeglądarce

To czysta wygrana w jakości życia i nasz faworyt w wydaniu. Testowanie maila kiedyś oznaczało wyzwolenie prawdziwego przepływu, a potem mrużenie oczu na zakładkę letter_opener albo testową skrzynkę. Podglądy pozwalają wyrenderować mailer w przeglądarce, z dowolnymi danymi, które ustawisz, po prostu wchodząc na URL:

# test/mailers/previews/user_mailer_preview.rb
class UserMailerPreview < ActionMailer::Preview
  def welcome
    UserMailer.welcome(User.first)
  end

  def password_reset
    UserMailer.password_reset(User.first)
  end
end

Wejdź na /rails/mailers/user_mailer/welcome, a zobaczysz wyrenderowanego maila, zarówno część HTML, jak i tekstową, odświeżaną przy każdym przeładowaniu, gdy poprawiasz szablon. Zamienia to projektowanie maili z wolnej, ślepej podróży w ciasną pętlę sprzężenia zwrotnego dokładnie jak praca nad zwykłym widokiem. Jeśli budujesz cokolwiek mocno mailowego, samo to uzasadnia aktualizację.

Enumy ActiveRecord: nazwane stany bez tabeli słownikowej

Kolumna statusu to niemal zawsze liczba całkowita udająca zbiór nazwanych stanów, ze stałą STATUSES = { ... } i stertą metod pomocniczych dokręconych ręcznie. Makro enum z 4.1 formalizuje dokładnie to:

class Order < ActiveRecord::Base
  enum status: [:pending, :paid, :shipped, :cancelled]
end

order.paid?          # => false
order.paid!          # ustawia status na :paid i zapisuje
order.status         # => "pending"
Order.shipped        # scope: wszystkie wysłane zamówienia

Przechowujesz kompaktową liczbę w bazie i pracujesz z czytelnymi nazwami w Ruby, dostając metody predykatów, settery z wykrzyknikiem i scope’y za darmo. Dwie ostre krawędzie do uszanowania, obie zakorzenione w tym samym fakcie — mapowanie jest pozycyjne. Przechowywana liczba to indeks w tablicy, więc wolno ci tylko dopisywać nowe stany; przestaw lub usuń jeden, a po cichu przemapujesz istniejące wiersze na złe znaczenie. Dla wszystkiego, gdzie to ryzyko jest nie do przyjęcia, użyj jawnej formy hasha, która przypina nazwy do liczb:

enum status: { pending: 0, paid: 10, shipped: 20, cancelled: 99 }

Jawny hash to to, czego używamy w praktyce — czyni wartości w bazie stabilnymi i samodokumentującymi się i zostawia luki, byś mógł później wstawiać stany.

Spring: preloader aplikacji

Spring trzyma twoją aplikację działającą w tle między komendami, więc rails console, rake i twój runner testów nie płacą wielosekundowego bootu Railsów za każdym razem. Na dużej aplikacji, gdzie boot potrafi trwać dziesięć–piętnaście sekund, to różnica między konsolą otwierającą się natychmiast a taką, której się boisz. W 4.1 jest włączony domyślnie w developmencie.

Kompromis jest jednak realny i warto go znać z góry: ponieważ aplikacja zostaje załadowana, Spring czasem serwuje ci przestarzały kod — najczęściej po zmianie inicjalizatora, dodaniu gemu albo edycji czegoś ładowanego przy bootcie. Poprawką jest odruch: spring stop (albo bin/spring stop) i pozwól mu się przeładować. Znajomość tej jednej komendy ratuje cię od sporadycznego, zbijającego z tropu momentu „ale ja to zmieniłem!”.

Warianty Action Pack: jedna akcja, wiele formatów

Warianty pozwalają pojedynczej akcji kontrolera wyrenderować inny szablon na podstawie żądania — najużyteczniej typu urządzenia — bez logiki rozgałęziającej wszędzie:

# w before_action
request.variant = :phone if browser_is_mobile?

# app/views/posts/show.html+phone.erb   -> serwowane telefonom
# app/views/posts/show.html.erb         -> domyślne

Rails wybiera show.html+phone.erb, gdy wariant to :phone, i w przeciwnym razie spada do zwykłego szablonu. To czysty sposób serwowania dopasowanego markupu różnym klientom z jednej akcji, komponujący się z resztą potoku renderowania, zamiast z nim walczyć.

Mniejsze dodatki

Jeszcze kilka wartych wzmianki: Module#concerning daje ci inline’owy sposób grupowania powiązanych metod wewnątrz klasy bez osobnego pliku concern; ActiveSupport::MessageVerifier i praca nad sekretami czynią podpisywanie/weryfikację danych prostymi; a zmiany w mailerach/sekretach porządkują sporo boilerplate’u, który generatory kiedyś rozrzucały.

Werdykt

4.1 to łatwa, niskoryzykowna aktualizacja o niezwykle dobrym stosunku małych funkcji do codziennego zysku. Podglądy mailerów i Spring zmieniają to, jak czuje się pracę nad aplikacją; secrets.yml i enum porządkują wzorce, które każda baza kodu wynajdywała ręcznie. Wdroż jawną-hashową formę enum, trzymaj wartości produkcyjne w ENV i naucz się odruchu spring stop, a praktycznie nie ma minusów. To Rails robiący to, co umie najlepiej — zauważa powtarzalne rzeczy, które wszyscy piszą, i wplata ich dobrą wersję do frameworka.