8

Jak wiadomo, wywołania zwrotne before_save są wykonywane przed wywołania zwrotne before_create.Is: on =>: create valid dla wywołania zwrotnego before_save w Railsach 3.2.3

Dlatego niektórzy sugerują, że lepiej byłoby użyć before_save :method, :on => :create zamiast before_create, aby metoda wywołania zwrotnego była wykonywana we właściwym czasie w stosunku do innych wywołań zwrotnych (takich jak wywołania zwrotne z funkcją automatycznego zapisu). Zobacz na przykład ten Pivotal Labs blog post i this StackOverflow answer.

Jednak, o ile mogę stwierdzić, opcja :on => :create nie osiąga pożądanego efektu na wywołania zwrotnym before_save. Innymi słowy, wywołanie zwrotne jest wykonywane dla każdego zapisu, niezależnie od tego, czy jest to tworzenie czy nie.

:on => :create opcja robi wydają się być ważne dla before_validation wywołań zwrotnych, choć.

Czy ktoś mógłby potwierdzić, że :on => :create ma działać pod numerem before_save? Czy to działało w poprzednich wersjach Railsów i jest teraz zepsute, czy te linki są po prostu błędne?

Zakładając, że :on => :create jest niepoprawny, czy dopuszczalne są poniższe i czy istnieje lepszy sposób?

before_save :callback_method, :if => :new_record? 

Dziękuję.

+0

złożyłam PR dla szyn dodać ścisłą kontrolę Argument: https://github.com/rails/rails/pull/30919 – seanlinsley

Odpowiedz

15

Masz rację, nie ma opcji dla wywołania zwrotnego before_save. Ale, nie rozumiem, po co używać before_save zamiast before_create. before_create oddzwanianie zostanie wywołane zaraz po before_save.

Oczywiście można użyć before_save :callback_method, :if => :new_record?. Ale osobiście nie podoba mi się to rozwiązanie - co zrobić, jeśli muszę dodać warunki w opcji :if?

Jeśli ktoś ma zależności między wywołaniami zwrotnymi before_save i before_create, proponuję połączyć 2 wywołania zwrotne. Na przykład (pseudokod):

class MyModel < ActiveRecord::Base 
    before_create :prepare_x 
    before_save :do_something_with_x 

    def prepare_x 
    @x = 10 
    end 


    # will not work, because `prepare_x` called after `do_something_with_x` 
    def do_something_with_x 
    @a = 100/@x 
    end 
end 

# || 
# || 
# \/ 

class MyModel < ActiveRecord::Base 

    before_save :do_something_with_x 

    def do_something_with_x 
    @x = 10 if new_record? 
    @a = 100/@x 
    end 
end 
+0

dzięki za odpowiedź, a w szczególności do potwierdzania że ': on =>: create' jest nieprawidłowe. Łączenie wywołań zwrotnych brzmi, jak może być dobrym pomysłem w ogólnym przypadku, ale nie jestem pewien, czy ma to zastosowanie w konkretnym przypadku próby przygotowania danych dla wywołania zwrotnego utworzonego przez skojarzenie autozapisu, prawda? – Nathan

+1

Odnośnie twojego pytania o to, dlaczego chcę używać before_save zamiast before_create: jest to dobrze wyjaśnione w blogu, do którego się odwołałem. Callback jest tworzony przez podstawowy kod Railsowy poprzez skojarzenie autozapisu. Wywołanie, które chcę utworzyć, musi zostać wykonane przed wywołaniem automatycznego zapisu, a wywołanie zwrotne before_create może nastąpić zbyt późno. – Nathan

+1

Szkoda, że ​​'before_save: on =>: create' nie działa po cichu. Byłoby miło, gdyby zadziałało lub rzuciło wyjątek. –

Powiązane problemy