【问题标题】:Rails3 - Validate a unique pair of indexesRails3 - 验证一对唯一的索引
【发布时间】:2011-05-05 02:17:01
【问题描述】:

我在迁移中创建了一个索引:

add_index "enrollments", ["student_id", "lecture_id"], :name => "index_enrollments_on_student_id_and_lecture_id", :unique => true

如何在 Rails 中验证这对密钥?我试过了:

validates_uniqueness_of :enrollment_id, :scope => [:student_id, :lecture_id]

但它不能正常工作。

另外,我需要在视图中找出这个键是否已经存在,或者是否可以创建一个新条目。

【问题讨论】:

    标签: sql ruby-on-rails ruby-on-rails-3 indexing validation


    【解决方案1】:

    很抱歉打开一个旧线程,但由于是 2011 年,我仍然找不到合适的验证器,我自己创建了一个:

    class UniqueSetValidator < ActiveModel::EachValidator
      def validate_each(record, attribute, value)
        setup record
        record.errors[attribute] << "- collection of fields [" + @fields + "] is not unique" if record.class.count(:conditions => @conditions) > 0
      end
    
      def check_validity!
        raise ArgumentError, "Must contain an array of field names' symbols" unless options[:in] && options[:in].respond_to?(:each)
      end
    
      private
    
      def setup record
        conditions  = []
        fields      = []
    
        options[:in].each do |field|
          conditions  |= [ field.to_s + " = '" + record[field].to_s + "'" ]
          fields      |= [ field.to_s ]
        end
    
        @conditions = conditions.join(" AND ")
        @fields     = fields.join(", ")
      end
    end
    

    这似乎对我有用。要使用它,请将代码粘贴到:

    your_rails_app/lib/unique_set_validator.rb
    

    并在以下位置启用它:

    your_rails_app/config/application.rb
    

    通过添加这一行:

    config.autoload_paths += %W( #{config.root}/lib  )
    

    然后你可以简单地在你的模型中使用它:

    validates :field, :unique_set => [ :field, :field2 ]
    

    它会验证pair [ :field, :field2 ] 的唯一性,任何错误都会返回到:field。我没有尝试过,但它应该适用于超过 2 个领域。

    我希望我没有搞砸任何事情,这将有助于某人。 :)

    【讨论】:

    • Voldy 的回答在 2010 年显示了正确的方法。使用 validates_uniqueness_of :field, scope: :field2 将验证一对值在数据库中是唯一的,附加来源 hereAPI docs
    【解决方案2】:

    试试这个!

    validates_uniqueness_of :enrollment_id, student_id, :scope => [:student_id, :lecture_id], :lecture_id], :message => "combination of enrollment, student and lecture should be unique."
    

    如果学生和讲座的组合不是唯一的,您将在错误消息中收到消息。

    更新:

    validates_uniqueness_of :student_id, :scope => [:lecture_id], :message => "combination of student and lecture should be unique."
    

    voldy 在回答中定义的方式是正确的方式。

    【讨论】:

    • 在注册模型中有id,而不是enrollment_id,它总是唯一的。
    【解决方案3】:
    class Enrollment < ActiveRecord::Base    
      validates_uniqueness_of :student_id, :scope => :lecture_id
    end
    

    如果您想在提交新注册之前在视图中确定这对存在,那么您可以使用 ajax 请求(我更喜欢带有 JQuery 的 RJS)并通过以下方式进行检查:

    class Enrollment < ActiveRecord::Base    
      def self.pair_exists?(student_id, lecture_id)
        Enrollment.find_all_by_student_id_and_lecture_id(student_id, lecture_id).any?
      end
    end
    

    希望这会对你有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-01
      • 1970-01-01
      • 2018-04-30
      • 1970-01-01
      • 1970-01-01
      • 2012-06-20
      • 2021-07-22
      相关资源
      最近更新 更多