在create action中使用build in has_many关系会导致质量分配错误

时间:2013-04-08 11:39:35

标签: ruby-on-rails params mass-assignment

我有一个质量分配错误我只能修复UGLY代码。我一定做错了什么。 让我解释一下:

我的rails应用程序客户端有很多联系人。 “客户端”页面显示属于该客户端的联系人列表。 我希望能够在列表中添加新联系人。所以我使用...

将客户端传递给联系人控制器
<%= link_to('new contact', new_contact_path(client_id: @client)) %> 

在ContactsController ....

def new
 client=Client.find(params[:client_id])
 @contact=client.contacts.new
end


def create
  @client = Client.find(params[:contact][:client_id])
  @contact= @client.contacts.build(params[:contact])
      if @contact.save
 ...

“保存”会产生一个不足为奇的错误:

  

无法批量分配受保护的属性:client_id

因为联系参数包含在联系人模型中不是(也不应该)attr_accessible的client_id

我知道如何解决问题的唯一方法是单独设置每个参数(不包括client_id),如下所示:

@contact= @client.contacts.build(first_name: params[:contact][:first_name], last_name:     params[:contact][:first_name], email: params[:contact][:email])

这种方法有效,但一切似乎都错了。肯定是一些更优雅的选择。 任何帮助表示赞赏。 (是的,我是铁杆新手)

1 个答案:

答案 0 :(得分:1)

要跳过该部分告诉您应该如何修复错误,我想先告诉您应该如何进行编码:)如果我错了,请更正。

Routes.rb你应该放(如果不是这样):

resources :client do
    resources : contacts
end

然后,在你view文件中的第二个,你应该放这样的东西:

<%= link_to('new contact', new_client_contact_path(@client)) %> 

通过这种方式,您无需在创建操作中执行任何操作,rails将管理所有其他操作。 这就是它应该完成的方式

编辑:

只是为了让它更清晰。 在new控制器的contacts操作中,您应该放置:

user= user.find(params[:user_id])
#2nd you build a new one
@contact= user.contacts.build

create控制器的contacts操作中,您应该输入:

user = User.find(params[:user_id])
#2nd you create the contact with arguments in params[:contact ]
@contact = user.contact.create(params[:contact ])
response .....