失去理智。一直在阅读文档和示例,并且已经能够解决这个问题。我可能遗漏了一些非常明显的东西。
模型
class Item < ActiveRecord::Base
belongs_to :collection
has_many :item_ownerships, :dependent => :destroy
accepts_nested_attributes_for :item_ownerships
validates :collection, :presence => true
end
class ItemOwnership < ActiveRecord::Base
belongs_to :item
belongs_to :user
validates :user_id, :presence => true
validates :item_id, :presence => true
end
class User < ActiveRecord::Base
has_many :item_ownerships
end
控制器
class ItemsController < ApplicationController
before_action :authenticate_user!
before_filter(:except => :toggle_item_owned_state) do
@collection = current_user.collections.find(params[:collection_id])
end
def new
@item = Item.new collection_id: @collection.id
@item_ownership = @item.item_ownerships.build(:owned => true, :user => current_user, :item => @item)
end
def create
@item = @collection.items.build(item_params)
@item_ownership = @item.item_ownerships.build(:user => current_user, :item => @item)
#byebug
if @item.save!
redirect_to collection_items_path(@collection)
else
flash.now[:alert] = "There was a problem saving this item."
render "new"
end
end
def item_params
params.require(:item).permit(:name,
item_ownerships_attributes: [:id, :owned, :user, :item])
end
end
查看
<%= form_for [@collection, @item] do |f| %>
<div class="form-group <%= 'has-error has-feedback' if @item.errors[:name].present? %>">
<label class="sr-only" for="item_name">Item Name</label>
<%= f.text_field :name, :autofocus => true, :placeholder => "Item Name", :class => "form-control", :'aria-describedBy' => "itemNameBlock" %>
<% if @item.errors[:name].present? %>
<span id="itemNameBlock" class="error">Item <%= @item.errors[:name].first %></span>
<% end %>
<%= f.fields_for :item_ownerships do |io| %>
<%= io.check_box :owned %> Owned
<% end %>
</div>
<div id="signin_button_row">
<%= f.submit "Save" %>
<span id="forgot_my_password" class="right-justify">
<%= link_to "cancel", collection_items_path(@collection) %>
</span>
</div>
<% end %>
当我提交表单时,它失败并出现以下错误:
验证失败:商品所有权用户不能为空,商品所有权项不能为空
使用调试器,我在保存之前查看了@item和@item_ownerships中的值,它们如下:
(byebug) @item
#<Item id: nil, name: "test", created_at: nil, updated_at: nil, collection_id: 71>
(byebug) @item_ownership
#<ItemOwnership id: nil, user_id: 52, item_id: nil, owned: nil, created_at: nil, updated_at: nil>
我假设在提交表单时,实例化@item,将填充并保存关联中的所有值。
我将继续尝试找到类似的问题或文章,但任何帮助将不胜感激。
更新
值得注意的是,如果我删除了复选框视图中的fields_for,则会保存两个模型而不会出现验证错误。
Post Parameters provided as requested:
{"utf8"=>"✓",
"authenticity_token"=>"TMPET9Oq9eH8vbk7REVnmKEB5X8BqycSkio5XXdwsLSVqs8/Soz+uMyGJJZCnpOQgbwBESnkKmLts8oQKKiG/Q==",
"item"=>{"name"=>"testg",
"item_ownerships_attributes"=>{"0"=>{"owned"=>"1"}}},
"commit"=>"Save",
"collection_id"=>"71"}
答案 0 :(得分:0)
我花了一段时间,但我终于明白了。我完全误解了嵌套模型是如何工作的。
在'create'中,两个模型(items和item_ownerships_都是使用行中的item_params构建的:
@item = @collection.items.build(item_params)
结果,实例化@item_ownerships的以下行是不必要的。验证失败有两种方式:
1)用户失败,因为没有通过item_params传递的用户信息 2)项目失败,因为我应该使用:inverse_of执行验证(参考这篇文章:http://michaelwelburn.com/2014/02/10/rails-4-nested-object-creation-and-parent-presence-validation-error/)
无论如何,感谢任何回复并正在考虑回应的人。