简体   繁体   中英

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. 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 .

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.

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的“可验证”行为,它添加了它自己对电子邮件字段的唯一验证。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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