15

そうです、さまざまなオブジェクト タイプをお気に入りに登録できるポリモーフィックな関連付けがあります。そのため、人は製品や人などをお気に入りにすることができます。私がやりたいことは、誰かが Favorites モデルの検証の一意性を使用してお気に入りを複製するのを防ぐことです。

class Favorite < ActiveRecord::Base
 belongs_to :favoritable, :polymorphic => true
 belongs_to :user

 attr_accessible :user

 validates_presence_of :user
 validates :user_id, :uniqueness => { :scope => [:favoritable_type, :favoritable_id] }
end

検証は機能しているように見えますが、エントリを複製しようとすると、何らかの理由で user_id を使用して新しいお気に入りの行が作成されます。

ここに画像の説明を入力

この初期保存を停止する方法はありますか?

Rails が DB エントリを作成してから、favoritable_id と favitable_type で次のように更新しているようです。

  SQL (28.3ms)  INSERT INTO "favorites" ("created_at", "favoritable_id", "favoritable_type", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["created_at", Tue, 14 Aug 2012 10:26:31 UTC +00:00], ["favoritable_id", nil], ["favoritable_type", nil], ["updated_at", Tue, 14 Aug 2012 10:26:31 UTC +00:00], ["user_id", 23]]
   (7.8ms)  COMMIT
   (0.1ms)  BEGIN
  Favorite Exists (0.3ms)  SELECT 1 AS one FROM "favorites" WHERE ("favorites"."user_id" = 23 AND "favorites"."id" != 123 AND "favorites"."favoritable_type" = 'Style' AND "favorites"."favoritable_id" = 29) LIMIT 1
   (0.2ms)  UPDATE "favorites" SET "favoritable_id" = 29, "favoritable_type" = 'Style', "updated_at" = '2012-08-14 10:26:31.943937' WHERE "favorites"."id" = 123
   (6.7ms)  COMMIT
   (0.1ms)  BEGIN
4

2 に答える 2

26

注意深く観察すると、一意性の検証がうまく機能することがわかります:)

validates :user_id, :uniqueness => { :scope => [:favoritable_type, :favoritable_id] }

追加したデータ イメージを確認します。画像内では、2 番目のレコードが存在しないのに対し、最初のレコードは異なることがわかります。favouritableそのため、2 つのレコードは一意であり、問​​題ではありませんuniquenessが、論理的なギャップがあります。

厳密に 2 回目の入力を避けたい場合はfavouritable、必須フィールドとして保持してください

validates :favoritable_type, :favoritable_id, :presence => true
于 2012-08-14T11:06:24.057 に答える