我的学校模型与其学生有许多关联,并且与具有用户容量字段的许可证一对一关联。我想强制验证将学生规模限制在许可容量的范围内,以便我有以下设置:
class School < ActiveRecord::Base
has_one :license
has_many :students
delegate :user_capacity, :to => :license
validate :within_user_capacity
def within_user_capacity
return if students.blank?
errors.add(:students, "too many") if students.size > user_capacity
end
end
这是我用来测试此验证的规范,假设用户容量为100 :
it "should fail validation when student size exceeds school's user capacity" do
school = FactoryGirl.create(:school_with_license)
puts school.user_capacity # => 100
puts school.students.size # => 0
0...100.times {|i| school.students.build(...)}
puts school.students.size # => 100
#build the 101st student to trigger user capacity validation
school.students.build(...).should_not be_valid
end
但是,这总会导致失败 - 我看到了消息:
Failure/Error: school.students.build(...).should_not be_valid
expected valid? to return false, got true
修改
似乎是FactoryGirl的问题,规范中的puts语句告诉我关联大小正在增加,但是在触发验证时在模型内进一步调试表明它从未增加。即使我明确地将构建的记录保存在spec循环中。
答案 0 :(得分:1)
当你想声称学校无效时,你似乎断言最后添加的学生无效(build
返回新学生)。你需要做这样的事吗?:
school.students.build(...)
school.should_not be_valid
答案 1 :(得分:0)
尝试进行简单的验证,无需委托。
我在我的应用程序中检查了您的方法,它通常适用于Steve在其答案中建议的修复(School
应检查其有效性。)
所以我建议使用以下代码:
class School < ActiveRecord::Base
has_many :students
validate :within_user_capacity
def within_user_capacity
errors.add(:students, "too many") if students.size > 1
end
end
接下来,打开控制台:RAILS_ENV=test rails c
> school = FactoryGirl.create :school
> school.valid?
=> true
> school.students.build
> school.students.size
=> 1
> school.valid?
=> true
> school.students.build
> school.students.size
=> 2
> school.valid?
=> false
> school.errors
=> ... @messages={:students=>["too many"]} ...
如果可行,您可以修复您的Rspec代码。