[英]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.