2016-12-13 13 views
0

私は、ユーザーが持っているとトリガー表、およびTriggersUserRailsはJoin Tableの特定のIdの一意性を検証しますか?

と呼ばれるテーブルを結合するには、ユーザーごとにちょうど1トリガIDの範囲を定義することは可能ですか?たとえば、各ユーザーはtrigger_id: 1を1回しか使用できませんが、trigger_id: 3は、そのユーザーと一緒に必要な回数だけ結合テーブルに格納できます。

トリガーIDとユーザーIDの一意性についてモデルの有効範囲を定義することは可能ですか?特定のtrigger_idsに対してのみ可能ですか?

ありがとうございます!

+1

データベースレベルの制限はありませんが、[validation](http://guides.rubyonrails.org/active_record_validations.html)で行うことができます。 –

+0

"ただ一つ"の代わりに "範囲"を太字にする必要があります。LOL –

+0

OPの要件を誤解しました。 – max

答えて

1

トリガーを使用できる時間を保存する必要があります。

class AddAllowedUsesToTriggers < ActiveRecord::Migration[5.0] 
    def change 
    add_column :triggers, :allowed_uses, :integer, default: 1 
    end 
end 

そして、許可された最大に対してuser_triggersの数をチェックするカスタム検証を追加します。

class User 
    has_many :triggers, through: :user_triggers 
    has_many :user_triggers 
end 

class Trigger 
    has_many :users, through: :user_triggers 
    has_many :user_triggers 

    def available_to?(user) 
    # lets use -1 to represent infinity 
    return true if allowed_uses == -1 
    # otherwise evaluate if the user has reached the max allowed number 
    (allowed_uses - user_triggers.where(user: user).count) > 0 
    end 
end 

class UserTrigger 
    belongs_to :user 
    belongs_to :trigger 

    validates :trigger_available 

    def trigger_available 
    unless trigger.available_to?(user) 
     errors[:trigger] = 'has been expended by user' 
    end 
    end 
end 
+0

私はavailable_toという考えが好きです。私はそれを1秒間遊ぼう。ありがとうございました! – gwalshington

+1

私は、このルールを適用するデータベースレベルの制約を作成するための直接的な方法は認識していませんが、競合状態が問題になる可能性があります。たとえば、ダブルクリックすると、両方のリクエストがどちらかが挿入される前に 'user_triggers'の数をチェックすると、1つだけが許可されていても2行が' user_triggers'に挿入されます。 https://robots.thoughtbot.com/the-perils-of-uniqueness-validations – max