我想在一个列上指定一个唯一的索引,但我还需要允许NULL个值(多个记录可以有NULL个值).在使用PostgreSQL进行测试时,我发现我可以有一条NULL值的记录,但下一条记录会导致一个问题:

irb(main):001:0> u=User.find(5)
  User Load (111.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 5]]
=> #<User id: 5, email: "a@b.com", created_at: "2013-08-28 09:55:28", updated_at: "2013-08-28 09:55:28">
irb(main):002:0> u.email=nil
=> nil
irb(main):003:0> u.save
   (1.1ms)  BEGIN
  User Exists (4.8ms)  SELECT 1 AS one FROM "users" WHERE ("users"."email" IS NULL AND "users"."id" != 5) LIMIT 1
   (1.5ms)  ROLLBACK
=> false

如果数据库设置为NULL,那么它会判断是否存在列,如果第一个列的id为User,那么它会查看.有没有一种方法,不仅数据库可以允许,Rails也不会像上面那样先判断?

这个 idea 是用户不必输入邮箱,但如果他们输入,我需要能够通过他们的邮箱找到用户.我知道我可以创建另一个模型来将用户与邮箱联系起来,但我更愿意采用上述方式.

UPDATE: Here's the migration code I had created to add the email column:

class AddEmailToUsers < ActiveRecord::Migration
  def change
    add_column :users, :email, :string
    add_index :users, :email, :unique => true
  end
end

下面是我添加到User型号的代码:

validates :email, uniqueness: true

我忘了我在User型号上加了validates个电话.所以Rails首先判断是有道理的.我想唯一的另一个问题是,数据库拥有唯一索引和NULL个字段是否安全?有没有办法在Rails中指定我想要验证的邮箱是唯一的,除非是nil

推荐答案

您的迁移将起作用,并将允许多个null值(对于大多数数据库引擎).

但是用户类的验证应该如下所示.

validates :email, uniqueness: true, allow_nil: true

Ruby-on-rails相关问答推荐

使用超级用户角色和未知密码创建与POSTRES用户的连接

Web控制台不会出现在例外页面Rails 7.1.1上

一对多关联 counter_cache 在 Rails 中无法正确重新加载

我需要在我的 Rails 7 应用程序中保留 app/assets/config/manifest.js 吗?

如何保持 en.yml DRY?

我如何在不同的视图中使用助手

rails 3:将链接显示为按钮?

如何使用 Capistrano gem 为生产数据库 seeder ?

从 Authlogic 迁移到 Devise

Rails:使用 RSpec 测试命名范围

了解 Rails 验证:allow_blank 有什么作用?

Heroku 错误 R14(超出内存配额):我该如何解决?

如何让空白复选框作为假传递给参数

使用 oauth 和 twitter ruby​​ gem 时不断收到 OAuth::Unauthorized 错误

验证一个对象是否有一个或多个关联对象

确认后如何进行设计重定向

Rails 控制台中手动更新属性值的验证问题

has_many :通过 class_name 和 foreign_key

Heroku - 在浏览器中显示当前提交的哈希

为什么 Rails 需要 JavaScript 运行时?