私の学校のモデルには、その生徒との多数の関連付けと、ユーザー容量フィールドを持つライセンスとの 1 対 1 の関連付けがあります。学生のサイズをライセンス容量のサイズに制限するための検証を課したいので、次の設定を行いました。
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 ステートメントは、関連付けのサイズが増加していることを示していますが、検証がトリガーされたときにモデル内でさらにデバッグすると、増加していないことが示されます。ビルドされたレコードを仕様ループ内に明示的に保存したとしても。