Подтвердить что ты не робот

Когда использовать "validates_associated" v. "Принадлежит_to: parent,: validate => true"

Кажется, что в рельсах вы можете определить валидации ассоциации в двух местах, либо на самой ассоциации:

class Child

  belongs_to :parent, :validate => true

end

Или как обратный вызов проверки:

class Child

  belongs_to :parent

  validates_associated :parent

end

В чем разница между этими двумя методами?

Тестирование разницы

Я думал, что, возможно, первое создает противодавление и гарантирует, что родительский объект действителен только в том случае, если ребенок действителен:

то есть. (при установке: validate = > true)

child.valid? # => false
child.parent.valid? # => also evaluates to false because of the :validate => true condition


# do whatever it takes to make the child valid again
#...
child.valid? # => true
child.parent.valid? # => true

Однако я тестировал его, и этого не происходит. Итак, какая разница (если есть) между двумя методами?

4b9b3361

Ответ 1

Мне пришлось выкопать код Rails (3.0.7), чтобы найти некоторые отличия. Основная функциональность выглядит одинаково для меня - они оба, кажется, называют valid? в соответствующей записи (-ах).

Основные отличия, которые я обнаружил, появляются только при использовании функции :autosave или при уничтожении связанного объекта или его маркировке для уничтожения. Например, у меня есть:

class AbsentDate < ActiveRecord::Base
  belongs_to :user, :autosave => true, :validate => true
end

И я вижу следующее поведение:

user = User.new(:username => "Jimmy")
user.valid?                               # => true
ad = AbsentDate.new(:user => user)
user.username = nil                          
user.valid?                               # => false
ad.valid?                                 # => false
ad.errors.full_messages                   # => ["User username cannot be empty"]
ad.user.mark_for_destruction
ad.valid?                                 # => true

Обратите внимание, что маркировка пользователя для уничтожения привела к действительному абсентету. Также обратите внимание, что есть только одно сообщение об ошибке. Теперь рассмотрим этот случай:

class AbsentDate < ActiveRecord::Base
  belongs_to :user, :autosave => true
  validates_associated :user
end

Это то, что я вижу:

user = User.new(:username => "Jimmy")
user.valid?                                # => true
ad = AbsentDate.new(:user => user)
user.username = nil
user.valid?                                # => false
ad.valid?                                  # => false
ad.errors.full_messages                    # => ["User username cannot be empty", "User is invalid"]
ad.user.mark_for_destruction
ad.valid?                                  # => false

Два сообщения об ошибках на этот раз, а AbsentDate все еще ложно, хотя его пользователь был помечен для уничтожения. Я смог воспроизвести эти результаты, вызвав destroy вместо mark_for_destruction.

Последнее: если вы используете validates_associated, вы получаете несколько опций (:if, :unless, :on, :message), которые не будут иметь, если вы используете флаг belongs_to.