简体   繁体   English

验证多态关联模型中的范围唯一性

[英]Validate scoped uniqueness in polymorphic association models

Right, so I have a polymorphic association that allows for different object types to be favorited. 是的,所以我有一个多态关联,允许不同的对象类型被收藏。 So a person can favorite a product, or a person, or whatever. 所以一个人可以喜欢一个产品,一个人,或其他什么。 What I want to do is guard against someone duplicating a favorite using validates uniqueness in the Favorite model. 我想要做的是防止有人使用收藏夹模型中的验证唯一性来复制收藏夹。

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

The validation seems to be working but for whatever reason a new Favorite row is still created with the user_id when an attempt is made to duplicate the entry. 验证似乎正在起作用,但无论出于何种原因,当尝试复制条目时,仍然使用user_id创建新的Favorite行。

在此输入图像描述

Is there a way to stop this initial save? 有没有办法阻止这个初始保存?

It seems that Rails is creating the DB entry and then updating it with the favoritable_id and favoritable_type as follows: 似乎Rails正在创建数据库条目,然后使用favoritable_id和favoritable_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

If you closely observe you can find that uniqueness validation just work fine :) 如果你仔细观察你可以发现唯一性验证工作正常:)

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

Look at the data image you added. 查看您添加的数据图像。 inside image you can find out that second record is not having favouritable whereas first have which is different hence 2 records are uniq and its not issue with uniqueness but its your logical gap. 在图像中你可以发现第二个记录没有favouritable而第一个记录是不同的,因此2个记录是uniq并且它不是uniqueness问题,而是它的逻辑差距。

If you strictly wanted to avoid second entry then keep favouritable as mandatory field 如果严格想要避免第二项则保持favouritable为必填字段

validates :favoritable_type, :favoritable_id, :presence => true
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

Did you go through the similar post 你有没有通过类似的帖子

Rails 3 uniqueness validation with scope on polymorphic table Rails 3唯一性验证与多态表上的范围

It seems that add_index does matter. 似乎add_index很重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM