Validieren Sie die Eindeutigkeit des Gültigkeitsbereichs in polymorphen Assoziationsmodellen

Richtig, ich habe also eine polymorphe Assoziation, mit der verschiedene Objekttypen bevorzugt werden können. So kann eine Person ein Produkt oder eine Person oder was auch immer favorisieren. Ich möchte verhindern, dass jemand einen Favoriten dupliziert, indem er die Eindeutigkeit im Favoritenmodell überprüft.

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

Die Überprüfung scheint zu funktionieren, aber aus welchem ​​Grund auch immer wird eine neue Favoritenzeile mit der user_id erstellt, wenn versucht wird, den Eintrag zu duplizieren.

Gibt es eine Möglichkeit, diese anfängliche Speicherung zu stoppen?

Es scheint, dass Rails den DB-Eintrag erstellt und ihn dann wie folgt mit favoritable_id und favoritable_type aktualisiert:

  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

Antworten auf die Frage(3)

Ihre Antwort auf die Frage