0

我的学校模型与它的学生有很多关联,以及与具有用户容量字段的许可证的一对一关联。我想进行验证以将学生人数限制在许可证容量的范围内,因此我进行了以下设置:

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 语句告诉我关联大小正在增加,但是随着验证被触发,模型内部的进一步调试表明它从未增加。即使我明确地将构建的记录保存在规范循环中。

4

2 回答 2

1

build当您要断言学校无效时,您似乎在断言添加的最后一个学生无效(返回新学生)。你需要做这样的事情吗?:

school.students.build(...)
school.should_not be_valid
于 2013-03-14T19:08:16.943 回答
0

尝试进行简单的验证,无需委托。

我在我的应用程序中检查了您的方法,它通常适用于史蒂夫在他的回答中建议的修复(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 代码。

于 2013-03-15T05:03:21.117 回答