collection << on new_record? == false (hm:t) can be deferred?

hi everyone,
in this example I'm going to use a simple has_many :through

Browsing Rails' source I noticed that assigning some objects to a
collection when the record is new and then saving, I can pass every
kind of object, which passes validate_associated or not:

@test ={"document_id"=>nil, "created_at"=>nil, "updated_at"=>nil, "when"=>nil})

=> #<Report id: nil, document_id: nil, when: nil, created_at: nil,
updated_at: nil>

@test.reasons << Reason.find_or_create_by_content("pr") # invalid records mass fest, validation will occur on save

=> [#<Reason id: nil, content: "pr", created_at: nil, updated_at:


=> false # all green

On the contrary when the object (owner) is already in place, it bombs
out with an exception.

@test = Report.first

=> #<Report id: 1, document_id: 1, ...

@test.reasons << Reason.find_or_create_by_content("pr") # ACK

ActiveRecord::RecordInvalid: Validation failed: Content is too short
(minimum is 3 characters)

Nothing strange, I'm sure that's the correct behaviour, what I would
like to ask is if there's some chance to "defer" the assignment, i.e.
acknowledge @test that he will have some reasons but do not raise if
some of them are invalid, leaving the job to update_attributes in

Would be a patch useful, if currently there are no ways, regarding
this matter?

Would be a patch useful, if currently there are no ways, regarding
this matter?

It sucks that this is inconsistent, but I think this is probably going
to be a pretty tough problem for you to solve with a patch. Because
the presence of an object in the has_many :through collection requires
the existence of a record in the association table. Figuring out how
to handle the different permutations of validation methods along the
chain will probably be a little difficult.

In your case you could probably try either using the full set of
associated classes (i.e. creating the ReportReason object in your
controller). Or alternatively create and validate the reason object
on its own.

Mixing transient and persistent objects in a single graph leads to
some strange issues like this, so you're probably better off avoiding
the potential problems altogether.