When to use “validates_associated” v “validate => true”

后端 未结 1 378
别跟我提以往
别跟我提以往 2020-12-23 02:09

It seems that in rails you can define association validations in two places, either on the association itself:

class Child

  belongs_to :parent, :validate =         


        
相关标签:
1条回答
  • 2020-12-23 02:58

    I had to dig into the Rails (3.0.7) code to find some differences. The core functionality looks the same to me -- they both seem to call valid? on the associated record(s).

    The key differences that I did find only appear when using the :autosave feature or when either destroying the associated object or marking it for destruction. For example, I have:

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

    And I see the following behaviour:

    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
    

    Note that marking the user for destruction resulted in a valid AbsentDate. Also note that there is only one error message. Now consider this case:

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

    This is what I see happening:

    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
    

    Two error messages this time, and the AbsentDate is still false even though its user has been marked for destruction. I was able to replicate these results by calling destroy instead of mark_for_destruction.

    One last thing: if you use validates_associated, you get several options (:if, :unless, :on, :message) that you won't have if you use the flag on belongs_to.

    0 讨论(0)
提交回复
热议问题