非常简单的设置。我想确保我对ORM的理解是正确的。
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
这不起作用。该组将被保存,但链接表中没有创建成员资格记录。但是使用create vs build有效。它是如何工作的?
这里最好的方法是什么?
答案 0 :(得分:0)
此行为是设计使然。如您所述,您可以@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)。