3

Я перепрошу this question, потому что код и пример неверны (он действительно работает в показанном случае).Rails ActiveRecord: пропустить проверки для ассоциаций

Учитывая эти модели:

class Author < ActiveRecord::Base 
    has_many :books 
    validates_presence_of :email 
end 

class Book < ActiveRecord::Base 
    belongs_to :author 
    validates_presence_of :title 
end 

Мы можем пропустить проверку при создании книги:

b = Book.new 
b.save(:validate => false) 

Но если мы получаем недействительную книгу из базы данных и назначить его ассоциацию в Авторе, нам не разрешено экономить. Автор:

a = Author.new 
a.email = "foo" 
a.books = Book.all 
a.save! 

Это ошибка:

ActiveRecord::RecordInvalid: Validation failed: Books is invalid

Как пропустить проверки для связанных моделей книг, не пропуская их для Автора?

Отметьте, что сообщение has_many :books, :validate => false в Авторе не помогает: ассоциация молча отбрасывается с Автором сохраняется.

ответ

11

Попробуйте что

class Author < ActiveRecord::Base 
    has_many :books, :validate => false 
    validates_presence_of :email 
    after_save :save_invalid_books 

    def save_invalid_books 
    books.each do |b| 
     b.save(false) 
    end 
    end 
end 

Насколько я понимаю, Validate => ложный только позволяешь сохранить автор без остановки неверной книги, но сохранить ассоциацию вам нужна действительная книга, как вы изменит ключ author_id. Вы не можете изменить внутренности рельсов, но вы все равно можете обмануть его, сохранив автора без проверки, а затем обновите каждую книгу и принудительно сохраните (с сохранением (false)) сразу после.

Конечно, этот код можно улучшить разными способами, так как, вероятно, не обязательно сохранять все книги каждый раз для начала, но вы получаете идею.

+0

Спасибо! Ваш код работает. Я упустил из виду, что ассоциация обновляет внешний ключ (и, следовательно, модель должна быть действительной). – 2010-12-16 00:51:29

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