Reputation: 223
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:
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.
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
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