Reputation: 165
I need to make a form that can handle the creation of multiple records of the same model, and submit the information in a way that passes through Rails’ Strong Parameters. On the front-end, I dynamically add two new text fields for puppy name and breed and want to save them all to a form. But I'm having trouble passing the array of puppy name and breed through Strong Params; getting
unknown attribute ‘puppies’ for Puppy
I think it's something very simple I'm overlooking. Please help generate these puppies!
new.html.erb
<%= form_tag puppies_path do %>
<%= text_field_tag “puppies[puppies][]puppy[name]” %>
<%= text_field_tag “puppies[puppies][]puppy[breed]” %>
<%= submit_tag “Add Puppy” %>
<% end %>
which generates these parameters
"puppies"=>{"puppies"=>[{"puppy"=>{"name"=>"ribbon", "breed"=>"poodle"}}]}
and the Strong Params in the controller
class PuppiesController < ApplicationController
def index
@puppies = Puppy.all
end
def new
end
def create
puppies_array = puppies_params[:puppies].each do |puppy|
puppy[:puppy]
end
Puppy.create(puppies_array)
end
def show
@puppy = Puppy.find(params[:id])
end
private
def puppies_params
params.require(:puppies).permit({
puppies: [
puppy: [
:name,
:breed
]
]
})
end
end
Any ideas what I’m missing?
Pseudo code of what I want to pass through:
[(name, breed), (name, breed), (name, breed)]
How can I write it correctly? I'm following this tutorial https://medium.com/@dmccoy/how-to-build-html-inputs-to-submit-an-array-of-hashes-with-a-rails-form-tag-that-work-with-strong-f70a6c03d78e
Upvotes: 1
Views: 967
Reputation: 36880
To get to the array of attributes that you want, you can do this:
puppies_array = puppies_params[:puppies][:puppy].map{|puppy| puppy.values}
This takes the hash puppies
within puppy params, and takes the array of hashes in puppy
and then takes just the value part of the hashes in that array.
You'll get your pseudo-code result.
For info, note that puppy
in the map block has no special significance... it just indicates the instance of the array. You could just as easily do
puppies_array = puppies_params[:puppies][:puppy].map{|some_dog| some_dog.values}
Upvotes: 0
Reputation: 416
You haven't added rest of your controller code, but I am assuming you are using something like: Puppy.create(puppies_params)
But since you are nesting the params in your view, you will need to use Puppy.create(puppies_params[:puppies])
to ensure you are able to pass in the correct array of name and breed into the create
action.
Edit Since puppies array contains a hash with puppy key, we will need to extract those to get the final array of puppy attributes.
def create
puppies_array = puppies_params[:puppies].collect do |puppy|
puppy[:puppy]
end
Puppy.create(puppies_array)
end
My comment below has a shorthand for setting puppies array, you can use whichever version looks more readable and understandable to you
Upvotes: 1