Currently the :reject_if option on accepts_nested_attributes_for
rejects the nested attributes when #valid? is called on the parent
association. I think better behavior would be to reject the nested
attributes only upon saving the parent association. Consider this
case:
Class Gift < ActiveRecord::Base
has_many :contributions
accepts_nested_attributes_for :contributions, :reject_if => proc { |
a> a['amount'].blank? }
If Contribution has a :nickname attribute which is filled in on a
@gift form, when the form makes a round trip through a failed
validation, the nested contribution_attributes are rejected. The
better outcome is to preserver these attributes so the form contains
all the data the user entered. Ultimately, if the :reject_if
condition is met, the association will be rejected when @gift.save
succeeds.
Carlos, I saw you commented on the :all_blank Rails ticket. What's
your opinion on this? Worth ticketing?
If I really understood your problem, what Andrew said should solve
it... Just by adding 'nickname' to your :reject_if proc should
validate whenever you have a nickname or amount in
contribution_attributes.
The :reject_if should verify conditions you feel reasonable to discard
that record from being created and validated. This way, if the
contribution has no 'nickname' and 'amount', it'd be discarded.
The question is: When a form makes a round trip through validation, should it return containing the data the user originally entered? With non-nested attributes, we don’t arbitrarily discard data, why do we do this with nested attributes? In general, why are we discarding stuff in the validation process?
:nickname and :amount, :reject_if => proc {|a| a[‘amount’].blank?
Presence of :nickname is not required, but data added to it should still be preserved when my forms returns after failing validation on some other attribute. Otherwise, the user is left thinking “Hmm… I filled something in here, why is it empty?”
I can make this behave as I require, but the extra code I write is only there because AR is discarding data during validation. This feels wrong, doesn’t it?
The question is: When a form makes a round trip through validation, should it return containing the data the user originally entered? With non-nested attributes, we don't arbitrarily discard data, why do we do this with nested attributes? In general, why are we discarding stuff in the validation process?
Because, like Carlos said, it's meant as a mean to completely disregard records from being created in the cases where you don't deem the data important or entered by the user.
Say you create a few new objects, on the server or client side, so the user can make new records if they want to, but the user doesn't actually enter any data, that's when you'd want to reject it.
More specific, say the form has a checkbox, this means that even though the user didn't enter any information, there will still be data sent to the server. In those cases you'd use :reject_if to disregard it at all.
You should _not_ use it if you don't actually want to reject them, but use validation to see if the data that was sent satisfies the needs. In short, it's a different concern.