Reputation: 1173
I have a controller that looks like this:
def new
@columns = Column.where(:table_id => @table.id)
@row = Row.new(id: @table.id)
end
def create
row_params.each do |row_param|
@row = Row.new(row_param)
@row.column_id = params["column_id"]
if @row.save
redirect_to collection_rows_path, notice: 'item was successfully created.'
else
render action: 'new'
end
end
end
I have a form that looks like:
<%= form_for [@table, @row] do |f| %>
<% @columns.each do |column| %>
<%= column.id %>
<%= hidden_field_tag :column_id, column.id %>
<%= f.label :data %><br>
<%= f.text_field :data %>
<% end %>
<%= f.submit %>
<% end %>
Basically, I'm trying to send multiple params and have them inserted with the column. But I keep getting this error:
undefined method
stringify_keys' for ["data", "No"]:Array` when there is two columns which means there is two text fields and I insert "Hello" in the first one, and "No" in the second.
Two things: Why is it only reading the "No" on the second one instead of both the "Hello" and "No"? And also why am I getting this error?
Thanks for all help!
Upvotes: 3
Views: 836
Reputation: 5644
Answers to your questions:
It is only reading "No" which is your input in the last "Data" text_field since the two text_fields generated in your form_for save their input value in the same params key which is params[:row][:data]. What happens then is the latest value saved to the params[:row][:data] key overrides any previous value it had.
The error undefined method stringify_keys' for ["data", "No"]:Array
happens because you create 2 text_fields with the same name which is :data. When you submit the form, an Array is being submitted instead of a String that Rails expects when using text_field.
Solution to your problem:
This seems like an ideal use case for using a nested model form. Basing on your code, it looks like Row belongs_to Table. So in your Table model you'll need to add this code:
#app/models/table.rb
accepts_nested_attributes_for :row
Then add the following code in your RowsController:
#app/controllers/rows_controller.rb
def new
@columns = Column.where(:table_id => @table.id)
@columns.each do |column|
@table.rows.build(column_id: column.id)
end
end
def create
@table = Table.new(table_params)
if @table.save
redirect_to collection_rows_path, notice: 'item was successfully created.'
else
render :new
end
end
private
def table_params
params.require(:table).permit(rows_attributes: [:data, :column_id])
end
Then in your 'rows#new' view:
#app/views/rows/new.html.erb
<%= form_for @table, url: rows_path ,method: :post do |f| %>
<%= f.fields_for :rows do |r| %>
<%= r.object.column.name %>
<%= r.hidden_field :column_id, value: r.object.column_id %>
<%= r.label :data %><br>
<%= r.text_field :data %>
<% end %>
<%= f.submit %>
<% end %>
What the above code will do is allow you to create multiple rows for a column according to the number of columns the table has. This won't work though if a @table has no @columns yet. This assumes that you've created @columns for the @table already. Basing on your code though, it seems like that's already what you're doing.
Upvotes: 2
Reputation: 2328
you want to store 'data' as array in Row
In Rails model Row add
serialize :data, Array
in view
text_field_tag 'row[data][]'
You are getting only 'No' because form for does not know its an array so , it picks the last one And you are getting this error because rails does not know you want to store it as array , it excepts a string but got an array instead.
Upvotes: 1