2010-11-04 2 views
1

я создал индекс в моих миграциях:Rails3 - Проверка единственной пары индексов

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
class Enrollment < ActiveRecord::Base  
    validates_uniqueness_of :student_id, :scope => :lecture_id 
end 

Если вы хотите, чтобы определить, в представлении перед отправкой новой регистрации, что эта пара существует, то вы можете использовать Ajax запрос (я предпочитаю RJS с JQuery) и проверить его:

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 

Надеется, что это Вам поможет.

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

Если сочетание студента и лекции не уникально, чем вы получите сообщение в сообщениях об ошибках.

Update:

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

Путь voldy определяют в ответ, что это правильный путь.

+0

Это то, что у него уже есть. – ryeguy

+0

В модели регистрации есть 'id', а не' enrollment_id', и он всегда уникален. – Voldy

+0

@ Вольди, да, я не правильно прочитал вопрос. Ты прав. –

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 ] 

Он будет проверять уникальные ness of pair [: field,: field2], и любая ошибка будет возвращена в поле. Я не пробовал, но он должен работать для большего количества двух полей.

Надеюсь, что я ничего не испортил, и это поможет кому-то. :)

+0

ответ Вольди показал правильный подход в 2010 году.с помощью 'validates_uniqueness_of: field, scope:: field2' будет проверять, что пара значений уникальна в базе данных, дополнительный источник [здесь] (http://stackoverflow.com/questions/4870961/rails-validate-uniqueness-of- несколько столбцов) и [API docs] (http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#method-i-validates_uniqueness_of) –

Смежные вопросы