简体   繁体   English

Rails validates_uniqueness_of忽略范围

[英]Rails validates_uniqueness_of ignoring scope

I'm very new to Rails and am having trouble with Rails/ActiveRecord seemingly ignoring scope on a validates_uniqueness_of declaration in a project I've inherited. 我对Rails还是很陌生,但是在我继承的项目中,Rails / ActiveRecord似乎忽略了validates_uniqueness_of声明的作用域。 I have the following model: 我有以下模型:

class User < ActiveRecord::Base
  …
  validates_uniqueness_of :email, scope: :brand_id, allow_nil: true
  …
  belongs_to :brand
  …
end

There is an existing user record with an email of foo@bar.com and a brand_id of 1 . 有与现有用户记录emailfoo@bar.combrand_id1

When trying to update another user record with an id of 123 , email of foo@bar.com and a brand_id of 2 , I get a Validation failed: Email has already been taken error. 尝试更新id123emailfoo@bar.combrand_id2另一个用户记录时,我收到Validation failed: Email has already been taken错误。

I see the following two queries run one after the other when this error occurs: 发生此错误时,我看到以下两个查询一个接一个地运行:

SELECT  1 AS one FROM "users" WHERE ("users"."email" = 'foo@bar.com' AND "users"."id" != 123) LIMIT 1;
SELECT  1 AS one FROM "users" WHERE ("users"."email" = 'foo@bar.com' AND "users"."id" != 123 AND "users"."brand_id" = 2) LIMIT 1;

It looks like the second query is doing the correct uniqueness check, but the first one is ignoring the scope. 看起来第二个查询正在执行正确的唯一性检查,但是第一个查询忽略了范围。

Any tips on what to look at or how to debug further would be appreciated. 关于看什么或如何进一步调试的任何技巧将不胜感激。

There's nothing wrong with your logic in the model. 您的模型中的逻辑没有错。 There's something else that's stopping the Record to save. 还有其他一些原因导致记录无法保存。

Can you put the whole model? 你能把整个模型放吗?

class Artwork < ApplicationRecord

  ...

  validates_uniqueness_of :artwork_file_name, scope: :game_id

  ...

end


2.3.1 :810 > Artwork.new(artwork_file_name: 'asd', game_id: 100).save
   (12.5ms)  BEGIN
  Artwork Exists (92.1ms)  SELECT  1 AS one FROM `artworks` WHERE `artworks`.`artwork_file_name` = BINARY 'asd' AND `artworks`.`game_id` = 100 LIMIT 1
  SQL (64.1ms)  INSERT INTO `artworks` (`game_id`, `artwork_file_name`, `created_at`, `updated_at`) VALUES (100, 'asd', '2017-02-17 10:25:25', '2017-02-17 10:25:25')
   (17.9ms)  COMMIT
 => true
2.3.1 :811 > Artwork.new(artwork_file_name: 'asd', game_id: 100).save
   (0.2ms)  BEGIN
  Artwork Exists (0.5ms)  SELECT  1 AS one FROM `artworks` WHERE `artworks`.`artwork_file_name` = BINARY 'asd' AND `artworks`.`game_id` = 100 LIMIT 1
   (6.1ms)  ROLLBACK
 => false
2.3.1 :812 > Artwork.new(artwork_file_name: 'asd', game_id: 101).save
   (0.2ms)  BEGIN
  Artwork Exists (45.4ms)  SELECT  1 AS one FROM `artworks` WHERE `artworks`.`artwork_file_name` = BINARY 'asd' AND `artworks`.`game_id` = 101 LIMIT 1
  SQL (6.7ms)  INSERT INTO `artworks` (`game_id`, `artwork_file_name`, `created_at`, `updated_at`) VALUES (101, 'asd', '2017-02-17 10:26:05', '2017-02-17 10:26:05')
   (6.3ms)  COMMIT
 => true
2.3.1 :813 >

事实证明这是Devise的“可验证”行为,它添加了它自己对电子邮件字段的唯一验证。

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

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