bdwain
bdwain

Reputation: 1745

what are the limitations of inverse_of in rails 3 with ActiveRecord

I've been reading about inverse_of and everything I'm seeing online seems inconsistent and confuses me. If you look here, you can see

There are a few limitations to inverse_of support:

  • They do not work with :through associations.
  • They do not work with :polymorphic associations.
  • They do not work with :as associations.
  • For belongs_to associations, has_many inverse associations are ignored.

yet right above that, they give this example

class Customer < ActiveRecord::Base
   has_many :orders, :inverse_of => :customer
end

class Order < ActiveRecord::Base
   belongs_to :customer, :inverse_of => :orders
end

I think they're saying the first inverse_of does nothing, but if so why did they do it?

In addition, even though the above thing says inverse_of doesn't work with through assocations, this page says

If you are using a belongs_to on the join model, it is a good idea to set the :inverse_of >option on the belongs_to, which will mean that the following example works correctly where >tags is a has_many :through association):

and gives this example

@post = Post.first
@tag = @post.tags.build :name => "ruby"
@tag.save

The last line ought to save the through record (a Taggable). This will only work if the >:inverse_of is set:

class Taggable < ActiveRecord::Base
  belongs_to :post
belongs_to :tag, :inverse_of => :taggings
end

To me all of this seems inconsistent and highly confusing. But in general, I see no harm in just saying inverse_of on every relationship. Is that a problem? I've seen a lot of people ask this on SO and haven't seen a solid yes or no from anyone.

Upvotes: 7

Views: 473

Answers (1)

Adam
Adam

Reputation: 66

There is no detrient to always specifiying it and it will allow rails to optimise loading of objects so you can go up and down the a active record model relationship chain in both directions without getting strange bugs where changing a value on one object doesnt change it's reference.

The only problem with setting it where it doesnt work is with certain types as you said before and if they fail silently you'll be getting the affore mentione bugs if you go the wrong way down the method chain after changing something

this is from the rails API

d = Dungeon.first
t = d.traps.first
d.level == t.dungeon.level # => true
d.level = 10
d.level == t.dungeon.level # => false

The Dungeon instances d and t.dungeon in the above example refer to the same object data from the database, but are actually different in-memory copies of that data. Specifying the :inverse_of option on associations lets you tell Active Record about inverse relationships and it will optimise object loading.

Upvotes: 1

Related Questions