railsで複合uniqueのvalidationをつけてやる

mysqlrailsの両方に念のためつけます。

複合uniqueなんて、使うことあるのか?って思っていたけど、必要になりました。

忘れないために書いておきます。

まずは、migrationの書き方からです。

class CreateReactions < ActiveRecord::Migration
  def change
    create_table :reactions do |t|
      t.references :icon, index: true, foreign_key: true, null: false
      t.integer :reactionable_id, null: false
      t.string :reactionable_type, null: false
      t.string :user_cookie_value, null: false

      t.timestamps null: false
    end

    add_index :reactions, [:reactionable_id, :reactionable_type]
    add_index :reactions,←ここから
      [:user_cookie_value, :icon_id, :reactionable_id, :reactionable_type],
      unique: true,
      name: :index_reactions_on_uniq_cookie_and_ids
  end
end

そして、rails

class Reaction < ActiveRecord::Base
  belongs_to :icon
  belongs_to :reactionable, polymorphic: true

  validates_uniqueness_of :reactionable_id, scope: [:icon_id, :user_cookie_value, :reactionable_type]←scopeで判定する
end

scopeで値を絞ります。

参考

ActiveRecord::Validations::ClassMethods

以上です。