15

对,所以我有一个多态关联,允许收藏不同的对象类型。所以一个人可以喜欢一个产品,一个人,或者其他什么。我想要做的是防止有人使用验证收藏模型中的唯一性来复制收藏。

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 正在创建数据库条目,然后使用 favouritable_id 和 favouritable_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] }

查看您添加的数据图像。在内部图像中,您可以发现第二条记录没有,favouritable而第一条记录不同,因此 2 条记录是唯一的,它不是问题,uniqueness而是您的逻辑差距。

如果您严格希望避免第二次输入,请保留favouritable为必填字段

validates :favoritable_type, :favoritable_id, :presence => true
于 2012-08-14T11:06:24.057 回答
7
class Favorite < ActiveRecord::Base

  belongs_to :user
  belongs_to :favoritable, polymorphic: true

  validates :user_id, :favoritable_id, presence: true,
    numericality: { only_integer: true }

  validates :favoritable_type, presence: true,
    inclusion: { 
      in: %w(FirstModelName SecondModelName),
      message: "%{value} is not a valid" 
    }

  validates :user_id, uniqueness: { scope: [ :favoritable_type, :favoritable_id ] }
end
于 2014-01-07T09:43:47.153 回答