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.