Подтвердить что ты не робот

Почему я не хочу использовать inverse_of всюду?

Как указано здесь:

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

inverse_of указывает, что Rails кэширует в ассоциациях памяти и минимизирует запросы к базе данных. Их пример:

 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

с которым они немедленно следуют:

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

Итак, у меня есть несколько вопросов.

  • Заменяются ли обратные ассоциации на has_many для a belongs_to? Если да, то как их пример имеет смысл? Разве он не должен ничего делать?
  • Насколько я могу судить (при условии, что он что-то делает) Все это позволяет сделать что-то вроде:

    dungeon.traps.first.dungeon
    

    с окончательным вызовом .dungeon НЕ генерирует весь новый запрос, а просто достигает связи с памятью. Предполагая, что это правильно, почему я никогда не хочу этого поведения? Почему бы мне просто не вставить inverse_of: в каждую ассоциацию?

4b9b3361

Ответ 1

Я начал писать об инверторе rails и как когда ассоциация не является прямым перегибом модели, которую вы используете inverse_of, чтобы указать, что это такое. Но потом я прокрутил к разделу, который вы упомянули, и вот как я это вижу. У вас есть что-то вроде:

# let 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

Конечно, dungeon.traps.first.dungeon не имеет смысла, и я сомневаюсь, почему это существует. Лично я не вижу, где и как я буду использовать это, но пример, который они дают, кажется, заполняет прецедент. Это происходит следующим образом:

# 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

Надеюсь, что это прояснит ситуацию.

Ответ 2

Отличные новости! В Rails 4.1 основные ассоциации * будут автоматически настроены inverse_of.

* Больше удобства означает больше случаев сложения... auto inverse_of работает только для ассоциаций, которые не задают один из следующих параметров:

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

Ресурсы

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