2012-09-30 12 views
5

Mongoidまたは標準のRailsバリデーターで問題があるかどうかはわかりませんが、無効な文書はまだデータベースに保存されています。無効なカスタム検証にもかかわらず、文書を保存している人がいます

私のようなものに設定したモデルがあります:私は、次の試験に合格するために期待されるが、それはない

class League 
    include Mongoid::Document 

    has_many :teams 

    validate do 
    if teams.size > 12 
     errors.add(:teams, 'too many teams') 
    end 
    end 
end 

class Team 
    include Mongoid::Document 

    belongs_to :league 
end 

を。 12個以上のチームがリーグに追加されないようにする私のカスタム検証の代わりに、リーグは13チームで節約されます。私はビルドを使用しての代わりに、league.teams << FactoryGirl.build(:team)を作成するために、13番目のチームを追加し、テストに行を変更した場合

# Factory for a League. 
FactoryGirl.define do 
    factory :league do 
    name "Test League" 

    factory :league_with_teams do 
    ignore do 
     teams_count 5 
    end 

    after(:create) do |league, evaluator| 
     FactoryGirl.create_list(:team, 
           evaluator.teams_count, 
           league: league) 
    end 
    end 
end 

describe League do 
    it "should not allow more than 12 teams" do 
    league = FactoryGirl.create(:league_with_teams, teams_count: 12) 
    league.teams << FactoryGirl.create(:team) 
    league.should_not be_valid # passes 
    League.find(league.id).teams.size.should eq(12) # fails 
    end 
end 

面白いことは、あり、テストは合格します。しかし、これは解決策ではありません。リーグは、追加されるチームが新規であるか、すでにDBに入っているかどうかにかかわらず、12チーム以上を持つことができないことを保証したいからです。

これを保証する方法はありますか?

編集

私は以下のようにやった、どちらか動作するようには思えない、チームモデルにバリデータを追加します。

class Team 
    include Mongoid::Document 

    belongs_to :league 

    validate do |team| 
    if league.teams.size > 12 
     errors.add :base, "cannot have more than 12 teams in a league" 
    end 
    end 
end 

私はこの問題は<<pushはアトミック操作であるという事実に関係していると考えているので、彼らはコールバックと検証をスキップします。つまり、これはかなり一般的な用途でなければならないのですか?では、他の人がどのように参照されている文書の数を検証していますか?

+0

検証で問題が解決していないようチーム – apneadiving

+0

にする必要があります。 – Marcus

+0

あなたは何を正確にしましたか? – apneadiving

答えて

0

私はこの問題が<<またはpushメソッドであるとは考えていません。両方ともモデルの検証をトリガーする必要があるからです。

は、使用してみてください:

league.teams << FactoryGirl.create(:team, league: league)

+0

私はmongoidのmasterブランチのafter_addコールバックとbefore_addコールバックを使用してこれを動作させる必要がありました。アトムプッシュメソッドはバリデーションを実行しません。 – Marcus