2012-06-02 13 views
8

Mam dwa modele z jednym do wielu skojarzeń. Chcę ustawić wartość domyślną na modelu podrzędnym podczas inicjalizacji na podstawie pewnego stanu nadrzędnego. Obejmuje to wywołanie po wywołaniu wywołania zwrotnego after_initialize dla dziecka, które musi uzyskać dostęp do rodzica poprzez powiązanie belongs_to. Problem polega na tym, że podczas tworzenia wystąpienia dziecka za pomocą metody kompilacji powiązanie z elementem nadrzędnym jest zerowe w wywołaniu zwrotnym after_initialize. Czy to oczekiwane zachowanie? Jestem na szynach 3.0.6Asocjacja Railsów w after_initialize

przykładem zabawki:

class Merchant < ActiveRecord::Base 
    has_many :products 
end 

class Product < ActiveRecord::Base 
    belongs_to :merchant 

    after_initialize :set_default_value 

    def set_default_value 
     if merchant.state 
      self.foo = some_value 
     else 
      self.foo = some_other_value 
     end 
    end 
end 

A w kontrolerze:

product = merchant.products.build 

w wywołaniu set_default_value, kupiec jest zerowa, choć wydaje się, że powinnam nie bądź.

+1

Czy oryginalna instancja kupiec zostały jeszcze zapisane, zanim zadzwonisz kupca. products.build? – Pasted

+0

Tak, sprzedawca byłby istniejącym rekordem w bazie danych, więc miałby prawidłowy identyfikator. – Dino

+1

Próbowałem prawie dokładnie, jak masz to i pracował dla mnie. Jedyną różnicą jest to, że 'Produkty klasy' powinny być 'produktem klasy 'bez' s'. –

Odpowiedz

1

chciałbym zmienić kod w następujący sposób:

class Product < ActiveRecord::Base 
    ... 
    def set_default_value(state = merchant.state) 
    if state 
     self.foo = some_value 
    else 
     self.foo = some_other_value 
    end 
    end 
end 

Następnie zmienić abonenta do:

product = merchant.products.build(:state => merchant.state) 

Również znalazłem after_initialize callbacków być powolne. Inną możliwością jest przeniesienie logiki do konstruktora produktu.

product = merchant.products.build(:foo => merchant.state ? some_value : some_other_value) 

Eliminuje to również Prawo Demeter naruszenie z kodu (czyli produkt nie powinien wiedzieć/obchodzi stan handlowca jest).

0

Jestem po szynach 2.3 i mogę potwierdzić, że

product = merchant.products.build 

nie zwróci poprawną stowarzyszenie MERCHANT_ID w zwrotnego after_initialize

ale odkryłem, że to będzie działać poprawnie z

product = merchant.products.new 

Myślę, że naprawiono to za pomocą tego zatwierdzenia (naprawdę nie wiem, nie jestem obeznany z przepływem pracy git):

https://github.com/rails/rails/issues/1842

Ponieważ w szynach 3.1.11 działa zarówno build i new

0

Prawdopodobnie szukać inverse_of

has_many :products, inverse_of: :merchant