问题
I'm trying to create a list of items within a "Todo list", however, I'm not sure if I'm doing this correctly with nested attributes. I think using a nested attribute is the right attempt because there's going to be a large list of items, and it will be associated with the correct "Todo list" based on ids.
Example of what the tables might look like when records are populated
Todo table
id list
1 grocery shopping
2 health insurance
Item table
id todo_id name
1 1 buy milk
2 1 buy cereal
3 2 Blue Shield
4 2 Healthnet
5 1 buy cherries
Although, with my attempt below, my application is not saving any of the data into the Item
database.
Todo Controller
class TodoController < ApplicationController
def new
@todo = Todo.new
@todo.items.build
end
end
Todo Model
class Todo < ActiveRecord::Base
belongs_to :user
has_many :items
accepts_nested_attributes_for :items
end
Item Model
class Item < ActiveRecord::Base
belongs_to :todo
end
Todo View
<%= simple_form_for(@todo) do |f| %>
<%= f.input :list %>
<%= f.simple_fields_for :items do |g| %>
<%= g.input :name %>
<% end%>
<%= f.button :submit %>
<% end %>
I was able to have the name
field show up in my view, but when I save it, it doesn't save into the database, however, I'm able to save the list into the database, and then when I try to edit the record, the name
field doesn't show up anymore to be able to edit.
EDIT: to show create method
This is my current Create Method in Todo Controller
def create
@todo = Todo.new(todo_params)
respond_to do |format|
if @todo.save
format.html { redirect_to @todo, notice: 'Todo was successfully created.' }
format.json { render :show, status: :created, location: @todo }
else
format.html { render :new }
format.json { render json: @todo.errors, status: :unprocessable_entity }
end
end
end
Not sure if Edit needs to have something, but I only have this from generating a scaffold of Todo
def edit
end
EDIT 2 show todo_params
def todo_params
params.require(:todo).permit(:user_id, :list)
end
回答1:
You must add the nested params to your strong params
def todo_params
params.require(:todo).permit(:user_id, :list, items_attributes: [:id, :text, ...])
end
Note about todo_id :
You don't need to add :todo_id
in items_attributes
list, because you already have the TODO as context.
@todo = Todo.new(todo_params)
In the above code, your todo_params will contain some item_attributes linked to @todo
. ie, it's similar to doing
@todo.items.build
It will already create an item with a todo_id
corresponding to @todo.id
回答2:
You need to add the items to the list of whitelisted attributes
def todo_params
params.require(:todo).permit(
:user_id,
:list,
items_attributes: [ # you're missing this
:id,
:name
]
)
end
来源:https://stackoverflow.com/questions/31418928/ruby-on-rails-nested-attributes-not-saving-into-database