2009-11-11 11 views
16

Właśnie czytałem numer this question, który dotyczy nadania polu daty modelu ActiveRecord wartości domyślnej. Przyjęta odpowiedź pokazuje, jak ustawić domyślną wartość z kontrolera. Moim zdaniem taka logika biznesowa naprawdę należy do samego modelu.Jaką rolę mają konstruktory modeli ActiveRecord w Railsach (jeśli istnieją)?

Potem zacząłem się zastanawiać, czy to jest Java, prawdopodobnie ustawiłbym początkową wartość pola podczas deklarowania zmiennej instancji lub w konstruktorze. Ponieważ pola oparte na bazie danych nie muszą być jawnie deklarowane w modelach ActiveRecord, czy jest to coś, do czego można użyć metody modelu initialize? Jestem ciekawy, ponieważ nie widziałem zbyt wiele zastosowań konstruktorów dla modeli ActiveRecord w kodzie Railsa, na który patrzyłem. Czy mają do odegrania rolę, a jeśli tak, to co to jest?

Odpowiedz

21

Często robię to dla wartości domyślnych. Działa dobrze i nadal pozwala użytkownikowi go zmienić. Pamiętaj, że metoda initialize jest wywoływana, gdy mówisz MyObject.new. Jednak może warto przeczytać this blog entry (choć nieco nieaktualne) na temat korzystania z initialize.

Powinieneś użyć after_initialize zamiast initialize. Metoda inicjowania jest wymagana przez ActiveRecord :: Base do przygotowania wielu metod wygody. Jeśli w modelu zdefiniowana jest metoda after_initialize, wywoływana jest ona jako wywołanie zwrotne dla nowych, tworzenia, wyszukiwania i innych metod generujących instancje danego modelu.

Idealnie chcesz zdefiniować tak:

def after_initialize 
    @attribute ||= default_value 
end 

Należy również pamiętać, że nie mogą korzystać z tej zwrotnego jak inni, należy zdefiniować metodę o nazwie after_initialize (jak wyżej) dla go do pracy. Nie można wykonać następujących czynności:

after_initialize :run_some_other_method 
+1

Używam podobnej techniki do buforowania atrybutów wewnętrznych na podstawie pól, zamiast wykonywać te same obliczenia w kółko. – EmFi

+0

Doskonale dziękuję. A dla tych, którzy szukają wyjaśnienia, dlaczego musicie to zdefiniować - http://stackoverflow.com/q/3826153/242426 – plainjimbo

+1

Wygląda na to, że zmieniło się w Rails 4/ActiveRecord 4.2.0. Proszę zobaczyć [moja odpowiedź] (http://stackoverflow.com/a/29566511/210780) po więcej szczegółów. – ashes999

2

Zgodnie z tym blog, aktywny rekord nie zawsze używa nowego, więc inicjalizacja może nie zostać wywołana na twoim obiekcie.

2

@ Odpowiedź Tophera Fangio jest poprawna. Wygląda na to, że interfejs API ActiveRecord zmienił się nieco między jego odpowiedzią (2009) a teraz (2015).

dzień dzisiejszy (4 z ActiveRecord Rails 4.2.0), oto jak dodać inicjatorów according to the ActiveRecord docs:

class Widget < ActiveRecord::Base 
    after_initialize |new_widget| 
    new_widget.name ||= 'Unnamed Widget' 
    end 
end 

można zweryfikować z puts sprawozdania lub sprawdzając nowy obiekt z rails console że faktycznie inicjuje poprawnie .

Powiązane problemy