我对学校的模式有一个有很多的关联与它的学生以及一对一ASSOCATION与具有用户容量领域的许可证。我想强加验证来限制学生的大小许可证容量的,所以我有以下建立到位:协会大小/限制验证在规范测试失败
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一个问题,该规范内卖出期权的语句告诉我,该协会规模正在增加,但该模型作为验证内部进一步调试触发表明,它永远不会增加。即使我明确地将构建的记录保存在spec循环中。
善于思考,我想我正在寻找的是一个验证错误作为最后一个学生建立并超出了'user_capacity'尽快触发。这是否意味着我需要将验证移动到学生模型中?它并不完全让学校业务逻辑在学生模型中发生。无论如何,我试图断言学校的有效性而不是你所建议的那样,而且我还没有取得任何成功。 – Noz 2013-03-14 20:44:29
Rails模型的验证通常在调用'valid?'方法(通常作为'save'方法的副作用)而不是属性更改时触发。将验证移动到学生课是没有意义的,因为它关于学校的业务逻辑不是个别学生。我看不出为什么你的测试仍然失败,找出为什么我会尽快在'within_user_capacity'方法中添加'puts'语句来确认它被调用,并且'students.size'是你期望的。 – Steve 2013-03-14 21:00:07