Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 802
bdwain Avatar asked Apr 18 '13 07:04

bdwain


People also ask

What is the use of Inverse_of in Rails?

The :inverse_of option basically gives us two-way memory bindings when one of the associations is a :belongs_to .

What is dependent destroy in Rails?

Dependent is an option of Rails collection association declaration to cascade the delete action. The :destroy is to cause the associated object to also be destroyed when its owner is destroyed.

What is inverse Ruby?

The inverse() is an inbuilt method in Ruby returns the inverse of the given matrix.


1 Answers

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.

like image 173
Adam Avatar answered Nov 15 '22 08:11

Adam