Rails3 - 验证唯一的索引对

时间:2010-11-04 14:16:00

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

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

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]

但它无法正常工作。

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

3 个答案:

答案 0 :(得分: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

希望这会对你有所帮助。

答案 1 :(得分: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个领域。

我希望我没有弄乱任何东西,这对某人有帮助。 :)

答案 2 :(得分:0)

试试这个!

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在答案中定义的方式是正确的方式。