这是一个问题。我有我的模特:
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
这是我的控制器代码:
before_filter(:except => :toggle_item_owned_state) do
@collection = current_user.collections.find(params[:collection_id])
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(:owned => false, :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
我有几个控制器测试:
describe 'POST#create' do
context "with bad data" do
it "should not create a new record for 'items'" do
expect { post :create, :collection_id => batman_collection.id,
:item => { :name => '',
:item_ownership_attributes => { :owned => '1'} }
}.to change(Item,:count).by(0)
end
it "should not create new record 'item_ownerships'" do
expect { post :create, :collection_id => batman_collection.id,
:item => { :name => 'item_name',
:item_ownership_attributes => { :owned => '1'} }
}.to change(ItemOwnership,:count).by(0)
end
end
end
当我运行测试时,第二个测试失败:
1) ItemsController authenticated user POST#create with bad data should not create new record 'item_ownerships'
Failure/Error: expect { post :create, :collection_id => batman_collection.id,
expected #count to have changed by 0, but was changed by 1
# ./spec/controllers/items_controller_spec.rb:62:in `block (5 levels) in <top (required)>'
最终这也反映在观点中。现在,当我查看数据库时,我看不到创建的记录。我认为这是他发生的事,因为不知何故Count反映了内存中对象的数量,而不是db。
我如何处理这种情况。问题表现在于,当提交表单进行填充时,Item的验证失败,但是,ItemOwnership的多个实例最终会显示在表单上。
由于
答案 0 :(得分:0)
我发现了问题。我的第二次测试是错误的,因为它实际上正在向服务器提交有效请求,因为该名称&#39;不是空白。
我删除了它,现在测试通过了。
答案 1 :(得分:0)
默认情况下,即使父记录的验证失败,Rails也会保存从嵌套属性创建的记录。这就是Item.count
增加的原因。与.count
不同的collection#size
始终会查询数据库。
您需要做的是在Item上创建一个验证,告诉Rails项目无效,除非父集合有效。
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
validates_associated :collection #!
end
http://guides.rubyonrails.org/active_record_validations.html#validates-associated