我有三个模型,全部用于has_many:通过关系。它们看起来像这样:
class Company < ActiveRecord::Base
has_many :company_users, dependent: :destroy
has_many :users, through: :company_users
accepts_nested_attributes_for :company_users, :users
end
class CompanyUser < ActiveRecord::Base
self.table_name = :companies_users #this is because this was originally a habtm relationship
belongs_to :company
belongs_to :user
end
class User < ActiveRecord::Base
# this is a devise model, if that matters
has_many :company_users, dependent: :destroy
has_many :companies, through: :company_users
accepts_nested_attributes_for :company_users, :companies
end
这样可以很好地加载,并且连接可以很好地用于查询。但是,每当我做
之类的事情时@company = Company.last
@user = @company.users.build(params[:user])
@user.save #=> true
@company.save #=> true
User
记录和CompanyUser
记录都已创建,但company_id
记录中的CompanyUser
字段设置为NULL
INSERT INTO `companies_users` (`company_id`, `created_at`,`updated_at`, `user_id`)
VALUES (NULL, '2012-02-19 02:09:04', '2012-02-19 02:09:04', 18)
当你@company.users << @user
我确信我在这里做了些蠢事,我只是不知道是什么。
答案 0 :(得分:14)
你不能像这样使用 has_many:through ,你必须这样做:
@company = Company.last
@user = User.create( params[:user] )
@company.company_users.create( :user_id => @user.id )
然后您将正确定义关联。
<强>更新强>
对于以下评论,由于您已经 accepted_nested_attributes_for ,因此您的参数必须如下:
{ :company =>
{ :company_users_attributes =>
[
{ :company_id => 1, :user_id => 1 } ,
{ :company_id => 1, :user_id => 2 },
{ :company_id => 1, :user_id => 3 }
]
}
}
您可以自动为用户添加用户。
答案 1 :(得分:5)
我怀疑你的params[:user]
参数,否则你的代码看起来很干净。 We can use build method with 1..n and n..n associations too
,请参阅here。
我建议您先确保您的模型关联正常,然后打开console
并尝试以下操作,
> company = Company.last
=> #<Tcompany id: 1....>
> company.users
=> []
> company.users.build(:name => "Jake")
=> > #<User id: nil, name: "Jake">
> company.save
=> true
现在,如果记录保存得很好,请调试传递给构建方法的参数。
快乐调试:)
答案 2 :(得分:2)
如果您有一个has_many :through
关联,并且想要使用build
保存一个关联,则可以在Join Model中使用Emirates_to关联上的:inverse_of
选项来完成此操作
这是rails文档的一个修改示例,其中标签具有has_many:through与帖子的关联,并且开发人员正尝试使用build
方法通过联接模型(PostTag)保存标签:
@post = Post.first
@tag = @post.tags.build name: "ruby"
@tag.save
通常的期望是最后一行应将“直通”记录保存在联接表(post_tags)中。但是,默认情况下这将不起作用。 仅在设置:inverse_of时有效:
class PostTag < ActiveRecord::Base
belongs_to :post
belongs_to :tag, inverse_of: :post_tags # add inverse_of option
end
class Post < ActiveRecord::Base
has_many :post_tags
has_many :tags, through: :post_tags
end
class Tag < ActiveRecord::Base
has_many :post_tags
has_many :posts, through: :post_tags
end
因此对于上述问题,请在联接模型(CompanyUser)的belongs_to :user
关联上设置:inverse_of选项,如下所示:
class CompanyUser < ActiveRecord::Base
belongs_to :company
belongs_to :user, inverse_of: :company_users
end
将导致以下代码在联接表(company_users)中正确创建一条记录
company = Company.first
company.users.build(name: "James")
company.save