2016-08-16 4 views
2

私はモデルeclubを持っています。これには多数の招待があり、追加できる招待状の数を制限したいと思います。私のモデルは、このSO answerによると、私は破壊のためにマーク招待を心配ないです提供動作するはずです。このhas_manyアソシエーションの検証エラーが保存を妨げない

class Eclub < ActiveRecord::Base 
    has_many :invites, dependent: :destroy 
    validates :invites, length: {maximum: 50, message: 'The maximum number of invites have been sent' } 

のように見えます。私のrspecテストでは最初にeclubが作成され、50の招待状が正常に追加されます。その後、私は防ぐにはどうすればよい

invite = Invite.new(name: 'Too Many', email: '[email protected]') 
    eclub.invites << invite 
    expect(eclub).to be_invalid 
    expect(eclub.errors[:invites].first).to include 'maximum number' 
    expect(eclub.reload.invites.size).to eq 50 

最初の二つの期待が通過しますが、最後は

Failure/Error: expect(eclub.reload.invites.size).to eq 50 

     expected: 50 
      got: 51 

で失敗し、余分なコレクションに追加されてからいかがでしょうか?

+0

私はnを明確にしました。 – Obromios

答えて

4

この検証を追加するのに最適な場所はEclubが、Inviteモデルではありません。これを試してみてください:それは文字列であることをinvitesを想定しているので、

class Invite < ActiveRecord::Base 
    belongs_to :eclub 
    validate :check_invite_count!, on: :create 

    private 

    def check_invite_count! 
    return if eclub.nil? 
    if eclub.invites.count > 50 
     errors.add(:base, 'Cannot add more than 50 invites for an Eclub') 
    end 
    end 
end 

また、このコードvalidates :invites, length: {maximum: 50, message: 'The maximum number of invites have been sent' }が動作しません。

+0

それは私がこれまで見てきた最良のアイデアです。試してみましょう。 – Obromios

+0

この検証がいつ実行されるべきかに関する回答を編集しました。 –

+0

ありがとう、私はあなたの答えを受け入れ、それをupvoted。私はまた、それをきれいにするために編集し、ゼロのeclubのチェックを追加し、テストを> =に変更しました。 ==を使用すると、すべてが期待通りに機能していれば問題ありませんが、動作していないことに慣れています。 – Obromios

-1

validates lengthは、文字列の長さを測定するためのもので、おそらく整数ではうまく機能しません。

あなたはおそらく試してみたいことは、私がここに持っているもの、validates :numericality => {:maximum => 50}

EDIT そうで、おそらく文句を言わないの仕事のどちらか、それは招待の数(ない招待協会自体は)私たちが検証するために必要なものであることだとして、ので、ここであなたが望む何をすべきカスタムバリデータです:

validate :invite_count_is_ok 

private 

def invite_count_is_ok 
    return unless invites.present? 
    errors.add(:base, "You may only have up to 50 invites at a time") unless invites.count <= 50 
end 
+0

私は '' 'validates:invites、numericality:{maximum:50}' 'を試して、Factory(:eclub)に検証エラーを受け取りました。メッセージは '' 'ActiveRecord :: RecordInvalid:Validation failed:Invitesは数字ではありません.'''です。私は '' 'validates:invites、size:{maximum:50}' '' 'を試しましたが、これは' '未知のバリデータ:SizeValidator'''エラーのある非スターターでした。 – Obromios

+0

はい、招待回数が0のときに爆発しないようにするには、おそらく ':allow_blank => true'が必要です。実際に招待の数が<= 50であることを確認したいと思うでしょうカスタムバリデータが必要です...実際に自分が望むものを実行するバリデータは実際にはありません。私はあなたのための別のアイデアを追加するに行くだろう –

+0

私はこのようないくつかを試してみました問題は、それがエラーメッセージを追加しますが、招待が追加されないようにeclubを無効にマークしますコレクション。これまでに動作するのはJagdeepの提案だけですが、私はeclub上のバリデーターとしてこれを直接行うことはできません。私はまた、私がこの問題を見ていない元のSOの投稿に驚いています。 – Obromios

-2
validates(
    :invites, 
    numericality: { 
    greater_than_or_equal_to: 0, 
    less_than_or_equal_to: 50 
    } 
) 
+0

Taryn Eastの提案を実装したときと同じエラーが発生しました。 – Obromios

+0

これを試してくださいvalidates_length_of:招待状、最大:50 –

+0

これは私の元のバリデータと同じ問題を抱えていますが、eclubを無効とマークしますが、余分なeclubの節約を妨げません。 – Obromios

関連する問題