简单的has_many:通过关联
非常简单的设置。我想确保我对ORM的理解是正确的。简单的has_many:通过关联
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, through => memberships
end
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, through => memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
现在,当用户创建一个组时,我希望链接表中的成员记录得到填充。它应该是一个原子(交易)。
class GroupsController < ApplicationController
def create
@group = current_user.groups.build(params[:group])
if @group.save
flash[:notice] = "Group has been created."
redirect_to @group
else
flash[:alert] = "Group has not been created."
render :action => "new"
end
end
end
这不起作用。该组被保存,但没有在链接表中创建成员记录。然而使用创建vs构建工程。这是它应该如何工作?
这里最好的办法是什么?
此行为是设计使然。正如你所提到的,你可以做@group = current_user.groups.create(params[:group])
。
或者你可以添加一个额外的语句来创建的连接模型的表中的记录为:
@group = current_user.groups.build(params[:group])
if @group.save
@group.memberships.create(:user_id => current_user)
# redirect and notify
好,原因是简单地建立@group
并保存它不连接表中增加一个额外的记录。
事实上,在这种情况下,@group = current_user.groups.build(params[:group])
有点类似于@group = Group.new(params[:group])
。不同之处在于,在前一种情况下,current_user.groups
将包含@group
(您可以在重定向之前尝试在Groups#create
之前),但在做current_user.reload
后跟current_user.groups
将产生[]
。
做到这一点的最好方法有点类似于你的方法。有一个简单的创建行动:
def create
@group = Group.new(params[:group])
# if else for save and redirect
然而,这个工作提交Groups#create
params哈希表应包括user_ids为:
"group"=>{"name"=>"new group", "user_ids"=>["1", "2", "3"]}, "commit"=>"Create Group"
可能这就是为什么@ bruno077是问你的理由粘贴你的视图的代码,以获得关于传递的user_ids参数的想法。因此,如果新的组表单包含选择多个用户的字段,那么其简单的创建操作就像上面所示(因为user_ids参数)。但是如果有一个没有选择用户选项的新组表单,那么最好使用第一个选项(一个使用create)。
只有传递参数是group [name]&group [description]。问题的症结在于,如果社团在建立和创造方面存在固有的不对称性, if @ group.save; #创建成员资格; 是,它不是原子的,如果成员资格失败,你离开孤立组。 – 2012-02-20 07:31:14
即使有多个用户的表单,因为关联从来不会被使用,所以用Group.new创建也不会有任何帮助。它永远不会像上面那样简单的创建操作。 – 2012-02-20 07:53:10
是的,创建组然后创建成员资格的问题是原子性,因为它们是两个完全不同的事务。但是,我认为使用create,即'current_user.groups.create(params [:group])'作为一个单独的事务不应该有这样的问题。如果连接模型验证导致无法在连接表中创建记录,则事务将回滚。所以,不应该有一个与会员关系不密切的团体。 – prasvin 2012-02-20 07:59:45
你在@ group.save行中有一个错字,(if在开始时不应该有@) – bruno077 2012-02-20 02:19:59
是的,这只是一个粘贴它的错误。问题依然存在。 – 2012-02-20 02:25:11
你能粘贴你的视图的代码吗? – bruno077 2012-02-20 02:31:05