提前感谢您的帮助。
这可能会有点长。
设置 型号:
class Collection < ActiveRecord::Base
has_many :collection_ownerships
has_many :items
has_many :users, :through => :collection_ownerships
validates :title, presence: true, length: { maximum: 25 }
validates :description, length: { maximum: 100 }
end
class Item < ActiveRecord::Base
belongs_to :collection
has_many :item_ownerships, :dependent => :destroy
accepts_nested_attributes_for :item_ownerships
validates :name, :presence => true, length: { maximum: 50 }
validates :collection, :presence => true
end
class ItemOwnership < ActiveRecord::Base
belongs_to :item
belongs_to :user
validates :user, :presence => true
validates :item, :presence => true
end
控制器
class ItemsController < ApplicationController
before_action :authenticate_user!
before_filter(:except => :toggle_item_owned_state) do
@collection = current_user.collections.find(params[:collection_id])
@item_list = @collection.items
end
def toggle_item_owned_state
@item = Item.find_by_id(params[:item_id])
@io = @item.item_ownerships.find_by_user_id(current_user)
@result = @io.update_attributes(:owned => @io.owned? ? false : true)
respond_to do |format|
if @result
format.html { }
format.js {}
else
format.html { }
format.js {}
end
end
end
def index
end
def new
@item = @collection.items.new
@item_ownership = @item.item_ownerships.build(:owned => true, :user => current_user, :item => @item)
end
def create
@item ||= @collection.items.new(item_params)
@item_ownership ||= @item.item_ownerships.build(:user => current_user, :item => item)
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 edit
@item = @collection.items.find_by_id(params[:id])
end
def update
@item = @collection.items.find_by_id(params[:id])
if @item.update_attributes(item_params)
redirect_to collection_items_path(@collection)
else
flash.now[:alert] = "There was a problem saving this item."
render "edit"
end
end
def item_params
params.require(:item).permit(:name,
item_ownerships_attributes: [:id, :owned ])
end
end
视图的
<div class="row">
<span class="col-sm-12">
<div id="add_item">
<%= 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", :class => "form-control green_button" %>
<span id="forgot_my_password" class="right-justify">
<%= link_to "cancel", collection_items_path(@collection), :class => "new_colors terms" %>
</span>
</div>
<% end %>
</div>
</span>
</div>
问题的症状: 当我在失败的情况下提交表单(即没有提供名称)时,表单当前检测到验证并显示错误,但是,我现在在表单中出现两个名为“own”的复选框。每个失败的提交都会添加一个附加复选框(根据附加图像)。
有人可以帮忙吗?
更新
这个问题转向了奇怪的问题。我没有改变任何东西(我知道,我知道,你不相信)除了重新启动服务器,但现在即使有效数据也没有保存。我收到验证错误说:
验证失败:项目所有权用户不能为空,项目所有权项目不能为空
答案 0 :(得分:2)
在您的控制器create
操作中
def create
@item ||= @collection.items.new(item_params)
@item_ownership ||= @item.item_ownerships.build(:user => current_user)
if @item.save
redirect_to collection_items_path(@collection)
else
flash.now[:alert] = "There was a problem saving this item."
render "new"
end
end
分配@item_ownership
时,问题出在第三行,此变量此时始终为空,因此执行=
之后的代码。 @item.item_ownerships.build(:user => current_user)
始终构建新的item_ownership
并将其存储到@item
实例中。所以在第一次调用create之后,你将有两个item_ownerships
首先来自表单,第二个是新创建的。如果验证失败并且您再次发送表单,则您将从新创建的表单中有三个item_ownerships
两个实例等。
答案 1 :(得分:0)
@edariedl在解决初始响应方面处于正确的轨道上。第二行完全没必要。
我在另一个问题中提到的更新中提到的第二个问题:Losing mind over validation failure saving nested models