rails/rails — Issue #5134: Parent model not marked as invalid when associated record is invalid, but not dirty
Author: mitio
Created: 2012-02-22 21:04:04+00:00
State: open

### Summary

If we have a parent model and an associated collection, `valid?` on the parent may return `true` in some cases, even though at least one of the associated collection records is invalid (ie. has `errors` and its `valid?` returns `false`).

### Tested on

Rails 3.2.1 and `3-2-stable`.

### How to reproduce

Consider the following code:

class Product < ActiveRecord::Base
has_many :prices
end

class Price < ActiveRecord::Base
belongs_to :product
validates_numericality_of :price
end

Then, if we do:

product = Product.create
price = product.prices.create price: 0

price.valid? # => true
product.valid? # => true

price.price = 'foo'

price.valid? # => false
product.valid? # => true but INCORRECT

price.errors.full_messages # => ["Price is not a number"]
price.changed? # => false; notice: instance not marked as changed

The incorrect value of `product.valid?` is due to the fact that `price.changed?` is false and thus `product.valid?` does not check the `price` instance for validity. `price.changed?` is false, because `'foo'` gets type-casted to `0` and the price was already `0`.

This would not have happened if any of the following was true:

* `price.price` was not `0`, but some other number
* `price.changed?` was returning `true` due to other price fields having changed
* `price.new_record?` was `true` (not `false`, as in our case)

### Offending code

* [ActiveRecord::AutosaveAssociation#associated_records_to_validate_or_save](https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/autosave_association.rb#L256), which boils down to:
* [ActiveRecord::AutosaveAssociation#changed_for_autosave?](https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/autosave_association.rb#L247)

### Proposed solution

None yet. I'm working on it.