Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - How to use hidden field on form to pass a value of an object related to the one created on a form?

I am trying to pass an rfid_tag from a form that creates a device from a hidden_field. Device has_many rfids. The rfid already exists in the db.

Here is the code from the form:

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

Here is the code from the 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

I get the following error because rfid_tag is not an attribute of device. It is an attribute of rfid:

Can't mass-assign protected attributes: rfid_tag

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

Thanks.

like image 290
Joe Essey Avatar asked Dec 27 '22 07:12

Joe Essey


2 Answers

The mass-assign error is happening because you are passing :rfid_tag as part of the params[:device] attribute hash.

In your example code, the :rfid_tag field needs to be provided using the hidden_field_tag form helper. This will keep it from being included in the params[:device] hash.

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

You can then access it via params[:rfid_tag]. Your create method should still work.

like image 136
Dan Reedy Avatar answered Feb 15 '23 23:02

Dan Reedy


Do what Dan Reedy said and use a hidden_field_tag in your form.

I'm concerned about this line in your controller's create method:

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

That's good if your rfid also has many devices, so you have a many to many relationship. If an rfid tag goes with exactly one device though you'll probably need to change that to something like:

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

And of course be sure to handle the cases where the cabinet_id or the rfid_tag you get from the params hash are not found in the database. Can't ever count on user provided input to be valid or correspond to real records, even if it's from hidden fields.

like image 28
sockmonk Avatar answered Feb 16 '23 00:02

sockmonk