我试图提供一种方法来生成一个新对象(" List"),在一个模型中使用has_many关系在另一个模型中使用新的关联对象(" Item") (通过"分组")。我能够使表单正常工作,但无法弄清楚我所缺少的是为了正确完成创建过程。
Rails v.5.1.2,Ruby v.2.4.1
lists_controller.rb
def new
@list = current_user.lists.new
3.times { @list.items.build }
end
def create
@list = current_user.lists.new(list_params)
respond_to do |format|
if @list.save
format.html { redirect_to @list, notice: 'List was successfully created.' }
format.json { render :show, status: :created, location: @list }
else
format.html { render :new }
format.json { render json: @list.errors, status: :unprocessable_entity }
end
end
end
private
def set_list
@list = List.find(params[:id])
end
def correct_user
@list = current_user.lists.find_by(id: params[:id])
redirect_to lists_path, notice: "Not authorized to edit this list"
if @list.nil?
end
def list_params
params.require(:list).permit(:title, {
item_attributes: [
:id, :title, :url
]})
end
items_controller.rb
def new
@item = Item.new
end
private
def set_item
@item = Item.find(params[:id])
end
def item_params
params.require(:item).permit(:title, :body, :url, :created,
:list_ids => [])
end
end
list.rb模型
has_many :groupings, :dependent => :destroy
has_many :items, :through => :groupings
accepts_nested_attributes_for :items,
reject_if: ->(attrs) { attrs['title'].blank? || attrs['url'].blank? }
item.rb模型
has_many :groupings, :dependent => :destroy
has_many :lists, :through => :groupings
validate :has_lists?
accepts_nested_attributes_for :lists
attr_writer :list_titles
after_save :assign_lists
def list_titles
@list_titles || lists.map(&:title).join(' ')
end
private
def assign_lists
if @list_titles
self.lists = @list_titles.split(/\,/).map do |title|
if title[0..0]==" "
title=title.strip
end
title=title.downcase
List.find_or_create_by_title(title)
end
end
end
def has_lists?
errors.add(:base, 'This item needs to be assigned to a list before it can be saved.') if self.lists.blank?
end
grouping.rb模型
belongs_to :item
belongs_to :list
accepts_nested_attributes_for :item, :list
列表
<%= form_with(model: list, local: true) do |f| %>
<% if list.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(list.errors.count, "error") %> prohibited this list from being saved:</h2>
<ul>
<% list.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %>
<%= f.text_field :title, id: :list_title %>
</div>
<div>
<p><strong>Items:</strong></p>
<%= f.fields_for :items do |item| %>
<div>
<%= item.label :title %>
<%= item.text_field :title %>
<%= item.label :url %>
<%= item.text_field :url %>
</div>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
示例控制台输出
开始POST&#34; / list&#34;对于127.0.0.1在2017-09-19 13:12:53 -0700 ListsController处理#create as HTML 参数:{&#34; utf8&#34; =&gt;&#34;✓&#34;,&#34; authenticity_token&#34; =&gt;&#34; Y6rszWVUXDIVymuoBkXwvkw1pVbyC6mffiWIZzr7PVd1NT9JJi6rD72k5Fh2qU5Q5tEd0qn6bFYMSJnz2TgjAA ==&#34;,&#34 ; list&#34; =&gt; {&#34; title&#34; =&gt;&#34;网站&#34;,&#34; items_attributes&#34; =&gt; {&#34; 0&#34; = &gt; {&#34; title&#34; =&gt;&#34; Google&#34;,&#34; url&#34; =&gt;&#34; www.google.com&#34;},&# 34; 1&#34; =&gt; {&#34;标题&#34; =&gt;&#34; Yahoo&#34;,&#34; url&#34; =&gt;&#34; www.yahoo.com& #34;},&#34; 2&#34; =&gt; {&#34;标题&#34; =&gt;&#34; Bing&#34;,&#34; url&#34; =&gt;&# 34; www.bing.com&#34;}}},&#34;提交&#34; =&gt;&#34;创建列表&#34;} 用户负载(0.3ms)SELECT&#34;用户&#34;。* FROM&#34;用户&#34;用户&#34;。&#34; id&#34; = $ 1 ORDER BY&#34;用户&#34;。&#34; id&#34; ASC限制2美元[[&#34; id&#34;,2],[&#34;限制&#34;,1]] 未允许的参数:: items_attributes (0.1ms)BEGIN SQL(0.9ms)INSERT INTO&#34; list&#34; (&#34; title&#34;,&#34; created_at&#34;,&#34; updated_at&#34;,&#34; user_id&#34;)VALUES($ 1,$ 2,$ 3,$ 4)返回&# 34; ID&#34; [[&#34;标题&#34;,&#34;网站&#34;],[&#34; created_at&#34;,&#34; 2017-09-19 20:12:53.458577&#34;] ,[&#34; updated_at&#34;,&#34; 2017-09-19 20:12:53.458577&#34;],[&#34; user_id&#34;,2]] (0.3ms)COMMIT 重定向到http://localhost:3000/lists/24 完成302发现在7ms(ActiveRecord:1.6ms)
我还在清楚地学习 - 但是在这个论坛上尝试了各种相关的提示后,我无法理解这一点。谢谢你的帮助!
答案 0 :(得分:1)
定义params时,语法有些错误。它应该是这样的:(项目代替项目,你不需要{})
def list_params
params.require(:list).permit(:title,
items_attributes: [:id, :title, :url])
end
答案 1 :(得分:1)
你几乎就在那里但是你的控制台日志中报告了一个错误:Unpermitted parameter: :items_attributes
。
将item_attributes
中的items_attributes
更改为list_params
:
def list_params
params.require(:list)
.permit(:title, items_attributes: [:id, :title, :url])
end