2012-06-26 62 views
1

我需要一個至少有兩個條目的has_many關聯,我如何編寫驗證以及如何使用RSpec + factory-girl測試它?這是我到現在爲止,但它與ActiveRecord::RecordInvalid: Validation failed: Bars can't be blank失敗,我完全卡在RSpec測試。has_many至少有兩個條目

/example_app/app/models/foo.rb

class Foo < ActiveRecord::Base 
    has_many :bars 
    validates :bars, :presence => true, :length => { :minimum => 2} 
end 

/example_app/app/models/bar.rb

class Bar < ActiveRecord::Base 
    belongs_to :foo 
    validates :bar, :presence => true 
end 

/示例應用內/規格/工廠/ foo.rb

FactoryGirl.define do 
    factory :foo do 
    after(:create) do |foo| 
     FactoryGirl.create_list(:bar, 2, foo: foo) 
    end 
    end 
end 

/example-app/spec/factories/bar.rb

FactoryGirl.define do 
    factory :bar do 
    foo 
    end 
end 
+1

':length'是字符串,而不是關係。 – benzado

回答

3
class Foo < ActiveRecord::Base 
    validate :must_have_two_bars 

    private 
    def must_have_two_bars 
    # if you allow bars to be destroyed through the association you may need to do extra validation here of the count 
    errors.add(:bars, :too_short, :count => 2) if bars.size < 2 
    end 
end 


it "should validate the presence of bars" do 
    FactoryGirl.build(:foo, :bars => []).should have_at_least(1).error_on(:bars) 
end 

it "should validate that there are at least two bars" do 
    foo = FactoryGirl.build(:foo) 
    foo.bars.push FactoryGirl.build(:bar, :foo => nil) 
    foo.should have_at_least(1).error_on(:bar) 
end 
+1

對於通過關聯銷燬,您需要執行如下操作: if bars.select {| bar | !bar.marked_for_destruction?} size <2 errors.add(:bars,:too_short,:count => 2) end –

+0

確實,我們的代碼還檢查「已銷燬?」屬性'bar_count = bars.reject {| bar | bar.destroyed? || bar.marked_for_destruction? }。尺寸 –

2

你想用一個自定義的驗證

class Foo < ActiveRecord::Base 
    has_many :bars 
    validate :validates_number_of_bars 

    private 
    def validates_number_of_bars 
    if bars.size < 2 
     errors[:base] << "Need at least 2 bars" 
    end 
    end 
end 
+0

這很好,但我不會將'number_of_bars'這個方法命名,因爲這不是它計算的內容。更好的名字是'validates_number_of_bars'或讓它實際返回數字,然後編寫一個驗證規則將其視爲屬性。 – benzado

+0

當然,這只是一個例子 –

+0

沒有理由爲什麼一個技術的例子不能也是一個好樣式的例子。 – benzado

相關問題