2013-02-18 11 views
13

Jak wspomniano tutaj:Dlaczego NIE chciałbym używać odwrotności wszędzie?

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

inverse_of wydaje się powiedzieć Rails buforowania w pamięci stowarzyszeń i zminimalizować zapytań do bazy danych. Ich przykładem jest:

class Dungeon < ActiveRecord::Base 
    has_many :traps, :inverse_of => :dungeon 
    has_one :evil_wizard, :inverse_of => :dungeon 
end 

class Trap < ActiveRecord::Base 
    belongs_to :dungeon, :inverse_of => :traps 
end 

które natychmiast postępować z:

for `belongs_to` associations `has_many` inverse associations are ignored. 

Więc mam kilka pytań.

  1. Czy powiązania odwrotne są ignorowane pod numerem has_many dla belongs_to? Jeśli tak, to w jaki sposób ich przykład ma sens? Czy nie powinien po prostu nic nie robić?
  2. O ile mogę powiedzieć (zakładając, że nic nie robi) Wszystko to pozwala zrobić, to coś jak:

    dungeon.traps.first.dungeon 
    

    z ostatecznym wezwaniem do .dungeon NIE generowania całą nową kwerendę, ale tylko sięgając po w skojarzeniu z pamięcią. Zakładając, że to jest poprawne, dlaczego miałbym NIE chcieć takiego zachowania? Dlaczego nie miałbym po prostu kłaść inverse_of: na każdym skojarzeniu?

Odpowiedz

6

Zacząłem pisać o inflectorze szyn i o tym, kiedy skojarzenie nie jest prostą odmianą modelu, którego używasz inverse_of do wskazania, co to jest. Ale potem przewinąłem do sekcji, o której wspomniałeś i tak to widzę. Załóżmy, że masz coś takiego:

# let's pick a dungeon 
d = Dungeon.first 

# say you find also find a trap that belongs to this particular d 
t = Trap.find(...) 

# then t.dungeon is the exact same object as d 
d == t.dungeon 

Oczywiście dungeon.traps.first.dungeon naprawdę nie ma sensu i wątpię, to dlaczego ta istnieje. Osobiście nie widzę, gdzie i jak bym tego użył, ale przykład, jaki podają, wydaje się wypełniać przypadek użycia. To wygląda następująco:

# you have an attribute level on dungeon 
d.level # => 5 

# now say you have a comparison after a modification to level 
d.level = 10 

# now without inverse_of the following thing occurs 
d.level   # => 10 
t.dungeon.level # => 5 

# d was updated and since t.dungeon is a whole different object 
# it doesn't pick up the change and is out of sync but using invers_of you get 
d.level   # => 10 
t.dungeon.level # => 10 

# because d and t.dungeon are the very same object 

Mam nadzieję, że to wyjaśnia.

+0

więc to znaczy, że jeśli miałbym powiedzieć t.dungeon.level = 10 (zamiast d.level = 10), że d.level nie aktualizowane nawet jeśli ustawiłem inverse_of, ponieważ zostało zignorowane? i ogólnie, aktualizacja członka kolekcji nie zostanie zsynchronizowana z innymi instancjami tego członka? ale nadal nie wydaje się, aby problem stanowił odwrót wszędzie, przynajmniej w nadziei, że w końcu go wesprą, prawda? – bdwain

+0

@bdwain jest to dla mnie bardzo interesujące, ponieważ zawsze myślałem, że Railsy automatycznie wywnioskowały ten związek odwrotny (jeśli pasują do siebie). Po pojawieniu się tego ostatnio (podczas sprawdzania poprawności w modelu, który akceptuje_nested_attributes_for_powiązanego modelu), muszę zgodzić się z twoim wnioskiem: hojnie używaj 'inverse_of'. Nie mogę sobie wyobrazić żadnego powodu, by tego nie robić. – steve

4

Świetne wiadomości! W Rails 4.1 podstawowe skojarzenia * będą automatycznie automatycznie skonfigurować .

* Większa wygoda oznacza więcej przypadków na krawędziach ... automatyczny inverse_of tylko prace dla stowarzyszenia, które wykonują nie podać jedną z następujących opcji:

  • :through
  • :foreign_key
  • :conditions
  • :polymorphic

Zasoby:

http://edgeguides.rubyonrails.org/4_1_release_notes.html http://wangjohn.github.io/activerecord/rails/associations/2013/08/14/automatic-inverse-of.html

+0

"Nie dla": warunki "w podręczniku nie jest całkowicie poprawne, powinno być" Nie, jeśli "zakres" jest zdefiniowany ". – 244an

Powiązane problemy