3

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 methodstringify_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!

2 Answers 2

2
+50

Answers to your questions:

  1. 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.

  2. 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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer. Does this still save a column_id for each row? The row corresponds with the column, so how could I also get the column name next to the row in the form?
I've just updated my answer to show the column.name in the form for each row and to include the column_id in the form submission
Thanks again. But I get an error from @table.rows.build(column_id: column.id) that says unknown attribute: table_id
It doesn't seem like Row belongs_to Table since you got that error. What is the association between rows, tables and columns? If Row is supposed to belong to Table, you should have a table_id column in rows.
1

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.

2 Comments

Thanks Anil for the answer. But as soon I did this I got a Missing template rows/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]} error
i think you didn't set up relation very well ..have a look at this question stackoverflow.com/q/20752904/1970061 it might help you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.