在has_many上设置inverse_of:通过rails 4.1

dbo*_*d68 10 ruby-on-rails ruby-on-rails-4

文档暗示inverse_of将适用于除多态关联之外的所有内容. http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Setting+Inverses

然而,似乎inverse_of仍然不适用于has_many:through

例如,我在以下示例中尝试使用inverse_of的每个组合都不起作用

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 
Run Code Online (Sandbox Code Playgroud)

任何想法都应该有效吗?如果是这样,我将如何设置此示例中的inverse_of?

UPDATE

例如,我尝试过(也试过has_many:通过)

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
Run Code Online (Sandbox Code Playgroud)

也试过了

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
Run Code Online (Sandbox Code Playgroud)

小智 14

我在rails 4.1.6中遇到了同样的问题(这就是我偶然发现这个问题).

它花了一些试验和错误(和服务器重启),但以下工作对我来说:

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
Run Code Online (Sandbox Code Playgroud)

为清楚起见:

架构

例:

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
}
Run Code Online (Sandbox Code Playgroud)

所以基本上我只在连接模型中设置inverse_of


ddd*_*919 0

如果您只是通过关联使用,请执行以下操作

class Event  < ActiveRecord::Base
  has_many :attendances
  has_many :users, through: :attendances ## there must be  plural too
class User < ActiveRecord::Base
  has_many :attendances 
  has_many :events, through: :attendances
class Attendance < ActiveRecord::Base
  belongs_to :event
  belongs_to :user
Run Code Online (Sandbox Code Playgroud)

然后Event和会通过模型(通过db 中的表中的和)User相互搜索。要查看详细信息,请参阅Rails Association ExplianAttendanceevent_iduser_idattendances

如果你想使用inverse_of关联,这意味着关系将由它们自己而不是第三方进行约束。首先你可以这样做:

class Event  < ActiveRecord::Base
  has_many :attendances
  has_many :users, :inverse_of => :events
class User < ActiveRecord::Base
  has_many :attendances 
  has_many :events, :inverse_of => :users
class Attendance < ActiveRecord::Base
  belongs_to :event
  belongs_to :user
Run Code Online (Sandbox Code Playgroud)

然后你需要像这样更改你的迁移文件:

creata_table :events do |t|
  ....
  t.string, :user_id
end

creata_table :users do |t|
  ....
  t.string, :event_id
end
Run Code Online (Sandbox Code Playgroud)

Like@event.usersuser_id直接在用户模型中搜索用户,而不是通过考勤模型搜索用户。

BTW,through不能inverse_of一起使用,Rails 指南已明确说明。