简体   繁体   中英

How do I iterate through a hash in an objects param hash?

Rails (and coding) rookie here (I'm sure I'm just missing basic syntax structural stuff), I've created a form where the user can add as many field pairs as they like via AJAX (barely). This form will collect column titles for a 'sheet' and the associated data type (int, str... etc). The sheet will have item entries added later by users. I'm trying to make a Sheets controller create method that not only saves the title and description of the sheet, but also adds a record to the 'columns' table with the column title, data type and associated sheet id. When I submit the sheet form, I get the following params in the server terminal: (sorry I'm not sure how to wrap the code snippet)

{"utf8"=>"✓", "authenticity_token"=>"yMlnfO1EWptkEXp5+9AGCO5C3vHt62EUHoKjdWoUB8I=", "sheet"=>{"title"=>"test 33", "description"=>"Descriptions"}, "column"=>[{"title"=>"1", "type"=>"num"}, {"title"=>"2", "type"=>"int"}, {"title"=>"3", "type"=>"real"}, {"title"=>"fo", "type"=>"no"}], "commit"=>"Save Specsheet!"}

I'm trying to loop through the column hash to create a record on the columns table. Each hash would use the title and type values as entries on the table.

My create method:

   def create
@sheet = Sheet.new(sheet_params)
@sheet[:column].each do |key, value|
  @column = Column.new
  @column[:column_title] = key
  @column[:column_data_type] = value
  @column.save
end

if @sheet.save
  redirect_to @sheet
else
  flash[:error] = "Error saving sheet."
  render :new
end

end

My error is usually something like this: undefined method `each' for nil:NilClass

**@sheet[:column].each do |key, value|**
  @column = Column.new
  @column[:column_title] = key
  @column[:column_data_type] = value

So I know I'm messing up referencing the column hash and its key and values. I'm thinking I can .reduce something here? I have no idea. These kinds of basic structural questions don't really show up with googling, so please let me know what I'm doing wrong, and thank you for reading all of this! Cheers!

WORKING CODE (sorry for weird formatting)

  def create
@sheet = Sheet.new(sheet_params)

column_params.each do |value|
  @sheet.columns.build(value.permit(:title, :data_type))
end

if @sheet.save
  redirect_to @sheet
else
  flash[:error] = "Error saving sheet."
  render :new
end

end

      private
  def sheet_params
    params.require(:sheet).permit(:title, :description, :created_at, :updated_at, :column)
  end

  def column_params
    params.require(:column)
  end

When you are calling @sheet[:column] , you are referencing an instance of Sheet instead of the params that you are trying to cycle through.

If you are trying to associate Columns to Sheets in a has_many relationship, you can create Columns like:

column.each do |key, value| 
  @sheet.columns.new( 
    column_title: key
   column_data_type: value
  end
end  

(and then save block) in your controller. Where column are the params. This will indicate that the column belongs to the sheet instance.

If you are trying to make the Column record without the associations, you can do

column.each do |key, value|
  Column.new( 
    column_title: key
    column_data_type: value
  end 
end

(and then save block)

(Both assuming that your fields are named column_title and not just title .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM