【问题标题】:How to define a "unique" constraint on a column of MySQL table in Ruby on Rails 3?如何在 Ruby on Rails 3 中对 MySQL 表的列定义“唯一”约束?
【发布时间】:2011-05-23 06:31:50
【问题描述】:

我有一个包含一列的简单 MySQL 表:name

我想在这个列上定义一个唯一的约束。

我能做到:

class MyModel < ActiveRecord::Base
  validates_uniqueness_of :my_column_name
end

但它只适用于应用程序级别,而不是数据库级别。

你有什么建议?

【问题讨论】:

    标签: mysql ruby-on-rails ruby-on-rails-3 unique unique-constraint


    【解决方案1】:

    使用以下方法向数据库本身添加唯一约束:

    add_index :my_models, :my_column_name, unique: true
    

    ...通过迁移(您可能希望 my_column_name 也不接受任何空值:

    class CreateMyModels < ActiveRecord::Migration
      def change
        create_table :my_models do |t|
          t.string :my_column_name, null: false
    
          t.timestamps
        end
    
        add_index :my_models, :my_column_name, unique: true
    
      end
    end
    

    【讨论】:

    • 这个答案比其他答案要好得多。对于多列的唯一约束,可以这样add_index :my_models, [:my_column_name1, :my_column_name2], unique: true
    • 你如何测试这个?就 Rails 而言,违反此约束的尚未保存的模型仍然是有效模型,因为它通过了模型的应用层约束。必须尝试保存它然后从数据库中查看 RecordNotUnique 错误,这有点麻烦。
    • drewww:这通常在您有一个工厂方法创建模型和多个执行线程的情况下很有用,在这种情况下,应用程序层约束可能会被记录验证可能依赖于存在的事实所欺骗。其他记录(例如:唯一的用户名)
    • 这实际上是针对 Rails 4 的。问题 是否 说明 Rails 3,但这对我有帮助 :)
    • 谢谢sircapsalot。 AFAIK,自 Rails 1.1.1 (apidock.com/rails/v1.1.1/ActiveRecord/ConnectionAdapters/…) 以来,此语法一直相同。如果您指的是 unique: true vs. :unique => true,那实际上是 Ruby 1.9 中的一个 Ruby 更改。
    【解决方案2】:

    这不是很有帮助,但在数据库级别强制唯一性似乎没有一个很好的答案。来自Rails migration guide

    Active Record 方式声称智能属于您的模型,而不是数据库。因此,触发器或外键约束等将部分情报推回数据库的功能并未得到大量使用。

    validates_uniqueness_of 等验证是模型强制数据完整性的一种方式。

    虽然 Active Record 没有提供任何直接使用这些功能的工具,但 execute 方法可以用来执行任意 SQL。

    如果您真的想在数据库中强制执行唯一性,使用 ActiveRecord 执行方法自己运行 SQL 命令可能是最好的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-08
      • 1970-01-01
      相关资源
      最近更新 更多