bnzelener
bnzelener

Reputation: 223

Creating an associated object of true/false values in Rails with check_box

I'm building a Rails app for inventory tracking. When a user creates an inventory object, I want to create an associated inventory_condition object with a set of boolean values that describe different condition attributes.

  # schema.rb

 create_table "inventories", force: true do |t|
    t.integer  "tradein_id"
    t.string   "esn"
    t.float    "price_paid"
    t.string   "erase_method"
    t.string   "status"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "device_id"
    t.string   "resale_reference"
    t.integer  "condition_id"
    t.integer  "inventory_batch_id"
  end

  create_table "inventory_conditions", force: true do |t|
    t.string  "grade"
    t.boolean "bad_esn",                   default: false, null: false
    t.boolean "find_my_iphone_locked",     default: false, null: false
    t.boolean "broken_glass",              default: false, null: false
    t.boolean "broken_lcd",                default: false, null: false
    t.boolean "broken_charge_port",        default: false, null: false
    t.boolean "broken_buttons",            default: false, null: false
    t.boolean "broken_speaker_microphone", default: false, null: false
    t.boolean "broken_camera",             default: false, null: false
    t.boolean "broken_wifi",               default: false, null: false
    t.boolean "broken_cellular",           default: false, null: false
    t.integer "inventory_id"
  end

In my form for creating an inventory object I'm having trouble passing true/false values through as params that the controller can use to build an inventory_condition object.

  # _form.html.erb (inventory)

  <div class="form-group">
    <%= f.label :functional_condition %><br>
    <% @conditions.each do |x| %>
     <div class="checkbox">
      <label>
        <%= check_box "[:condition]", ":#{x}", {}, "true", "false"%> <%= x.humanize.split.map(&:capitalize).join(' ') %>
      </label>
    </div>
    <% end %>
  </div>

In my inventories_controller I build my inventory object in association to its parent inventory_batch, and then I try to create the inventory_condition object, which is a belongs_to child of the inventory class.

  # inventories_controller.rb

  def create
    @inventory_batch = InventoryBatch.find(params[:inventory_batch_id])

    @inventory = @inventory_batch.inventories.build(inventory_params)

    @condition = @inventory.inventory_conditions.build(inventory_conditions_params)
  end

When submitted, the condition parameters are:

":condition"=>{":bad_esn"=>"false", ":find_my_iphone_locked"=>"false", ":broken_glass"=>"true", ":broken_lcd"=>"true", ":broken_charge_port"=>"false", ":broken_buttons"=>"false", ":broken_speaker_microphone"=>"false", ":broken_camera"=>"false", ":broken_wifi"=>"false", ":broken_cellular"=>"false"}

Which is not suitable to pass through as strong_params.

Two questions:

  1. Is there a better way to store these condition attributes? I could put them right on each inventory object, but that didn't seem clean.

  2. What's the proper way to create the checkbox fields and pass them through the inventories_controller to build my inventory_condition object?

Edit - added full params when form is submitted

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"MWkzncKzxhsqn5DmyA3nRblCrTfTz3EgnF8BSKFWfjs=",
 "inventory"=>{"esn"=>"",
 "price_paid"=>"",
 "erase_method"=>"Pre-Erased",
 "inventory_conditions"=>{"bad_esn"=>"false",
 "find_my_iphone_locked"=>"false",
 "broken_glass"=>"false",
 "broken_lcd"=>"true",
 "broken_charge_port"=>"true",
 "broken_buttons"=>"false",
 "broken_speaker_microphone"=>"false",
 "broken_camera"=>"false",
 "broken_wifi"=>"false",
 "broken_cellular"=>"false"}},
 "Manufacturer"=>"",
 "Network"=>"Select the Network",
 "Model"=>"Select the Model",
 "Variant"=>"Select the Variant",
 "Capacity"=>"Select the Capacity",
 "Color"=>"Select the Color",
 "condition"=>"",
 "commit"=>"Save Inventory",
 "inventory_batch_id"=>"16"}

Upvotes: 2

Views: 454

Answers (1)

Ryan K
Ryan K

Reputation: 4053

Use the fields_for method:

# _form.html.erb (inventory)

  <div class="form-group">
    <%= f.label :functional_condition %><br>
    <%= f.fields_for :inventory_conditions do |i| %>
     <% @conditions.each do |x| %>
      <div class="checkbox">
       <label>
        <%= i.check_box "[:condition]", "#{x}".to_sym %> <%= x.humanize.split.map(&:capitalize).join(' ') %>
       </label>
     </div>
    <% end %>
   <% end %>
  </div>

Edit (this stuff is for the single strong params method):

That way, the inventory_conditions parameters are passed as a sub-hash of the inventories params. You need to update your strong params to include this:

inventory_conditions_attributes: [:broken_glass, :broken_lcd, etc...]

This MUST be at the end of your strong params list (i.e. after esn, status, etc).

Upvotes: 0

Related Questions