Rails - 如何在窗体上使用隐藏字段来传递与在窗体上创建的对象相关的对象的值?

时间:2013-03-14 20:00:51

标签: ruby-on-rails ruby

我正在尝试从rfid_tag创建device的表单中传递hidden_field。设备has_many rfids。数据库中已存在rfid

以下是表单中的代码:

<th>RFID Tag #</th>
<td>
  <%= f.label(:@passed_rfid_tag, @passed_rfid_tag) %>
  <%= f.hidden_field :rfid_tag, :value => @passed_rfid_tag %>
</td>
</tr>

以下是来自devices_controller的代码:

def create
   @cabinet = Cabinet.find(params[:device][:cabinet_id])
   @device = Device.create(params[:device])
   @device.rfids << Rfid.where('rfid_tag' => params[:rfid_tag]).first
   @device.row_id = @cabinet.row_id
   @device.save

我收到以下错误,因为rfid_tag不是device的属性。它是rfid

的属性
Can't mass-assign protected attributes: rfid_tag

app/controllers/devices_controller.rb:182:in `create'

感谢。

2 个答案:

答案 0 :(得分:7)

发生了质量分配错误,因为您将:rfid_tag作为params[:device]属性哈希的一部分传递。

在您的示例代码中,需要使用:rfid_tag表单帮助程序提供hidden_field_tag字段。这将使其不被包含在params[:device]哈希。

<tr>
  <th>RFID Tag #</th>
  <td>
    <%= label_tag 'rfid_tag', 'RFID Tag' %>
    <%= hidden_field_tag 'rfid_tag', @passed_rfid_tag %>
  </td>
</tr>

然后,您可以通过params[:rfid_tag]访问它。您的create方法仍应有效。

答案 1 :(得分:3)

执行Dan Reedy所说的并在表单中使用hidden_​​field_tag。

我在控制器的创建方法中关注这一行:

@device.rfids << Rfid.where('rfid_tag' => params[:rfid_tag]).first

如果你的rfid也有很多设备,这很好,所以你有很多关系。如果rfid标签只与一个设备配合使用,您可能需要将其更改为:

rfid = Rfid.where('rfid_tag' => params[:rfid_tag]).first
rfid.device_id = @device.id
rfid.save!

当然,一定要处理在数据库中找不到从params哈希获得的cabinet_id或rfid_tag的情况。无法指望用户提供的输入有效或与真实记录相对应,即使它来自隐藏字段。