Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting inverse_of on has_many :through rails 4.1

The documentation implies that inverse_of will work for everything except polymorphic associations. http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Setting+Inverses

However it appears inverse_of still doesn't work for has_many :through

e.g. every combination I have tried for inverse_of on the follow example doesn't work

class Event  < ActiveRecord::Base
  has_many :attendances
  has_many :users, through: :attendance
class User < ActiveRecord::Base
  has_many :attendances 
  has_many :events, through: :attendances
class Attendance < ActiveRecord::Base
  belongs_to :event
  belongs_to :user 

any ideas of this should work? and if so how I would set inverse_of in this example?

UPDATE

e.g. of what i tried ( also tried on has_many :through)

class Event  < ActiveRecord::Base
  has_many :attendances , :inverse_of => :event
  has_many :users, through: :attendance
end
class User < ActiveRecord::Base
  has_many :attendances , :inverse_of => :user
  has_many :events, through: :attendances
end
class Attendance < ActiveRecord::Base
  belongs_to :event, :inverse_of => :attendances
  belongs_to :user,  :inverse_of => :attendances
end

also tried

class Event  < ActiveRecord::Base
  has_many :attendances  
  has_many :users, through: :attendance , :inverse_of => :events
end
class User < ActiveRecord::Base
  has_many :attendances 
  has_many :events, through: :attendances ,:inverse_of => :users
end
class Attendance < ActiveRecord::Base
  belongs_to :event
  belongs_to :user
end
like image 976
dboyd68 Avatar asked Sep 26 '14 06:09

dboyd68


2 Answers

I had the same question in rails 4.1.6 (that's how I stumbled upon this question).

It took a bit of trial and error (and server restarts), but the following works for me:

class User < ActiveRecord::Base
  has_many :company_users
  has_many :companies, through: :company_users
end

class Company < ActiveRecord::Base
  has_many :company_users
  has_many :users, through: :company_users
end

class CompanyUser < ActiveRecord::Base
  belongs_to :company, inverse_of: :company_users
  belongs_to :user, inverse_of: :company_users
end

For clarity:

Schema

Example:

user = User.last
company = user.companies.build( ... )
company.save
# ...
# SQL (0.9ms)  INSERT INTO "public"."company_users" ("company_id", "created_at", "updated_at", "user_id") VALUES ($1, $2, $3, $4) RETURNING "id"  [["company_id", 4], ["created_at", "2014-10-03 03:40:58.836975"], ["updated_at", "2014-10-03 03:40:58.836975"], ["user_id", 1]]
(1.6ms)  COMMIT
CompanyUser.last
<CompanyUser:0x00000020339710> {
        :id => 4,
:company_id => 4,
   :user_id => 1,
:created_at => Thu, 02 Oct 2014 20:40:58 PDT -07:00,
:updated_at => Thu, 02 Oct 2014 20:40:58 PDT -07:00
}

So basically I only set the inverse_of in the join model

like image 93
minusoneman Avatar answered Nov 16 '22 10:11

minusoneman


The guides say inverse_of is not supported when using :through. Specifically:


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.

like image 40
Abraham Chan Avatar answered Nov 16 '22 08:11

Abraham Chan