On Wednesday, 13 February 2013 15:41:49 UTC-5, Rafael C. de Almeida wrote:
On Wednesday, February 13, 2013 12:59:11 PM UTC-2, Matt Jones wrote:On Tuesday, 12 February 2013 20:29:49 UTC-5, Rafael C. de Almeida wrote:Hello,
Have you guys noticed that conditional validation with validates_associated does not work well when you are creating a new record?
The Lawyer class has validates_associated on address conditioned on whether the Lawyer data comes from a known source or not. So, if lawyer.source equals to some string, then lawyer.address must not be validated. However, if I'm trying to create a new record, it is validated regardless of whether source is nil or not. Is it expected to behave like that? Is that a bug?
The behavior is intentional, though perhaps not documented as well as it should be. It has to do with the autosave behavior for has_many on new records - the part that enables you to build a new record, add some unsaved child records (phones, etc in your example) and then save the parent object and get all the others saved as well.
I see. Thank you for the clarification. However, isn't that behavior counter-intuitive? Why should "valid?" return a different thing depending on whether a nested model is saved or not? If you want to skip the validation of one nested model, but still validate other things, then your only option is doing something like:
Better option: don't save records to the DB that are invalid. That's typically considered a bad thing, so Rails makes it hard to do.
I'd recommend extending the "extracted?" method into your related models:
class Lawyer < ActiveRecord::Base
has_many :phones, :inverse_of => :lawyer
...
end
class Phone < ActiveRecord::Base
belongs_to :lawyer, :inverse_of => :phones
validates_something_of :foo, :if => :extracted?
def extracted?
lawyer.extracted?
end
end
This has the advantage of making the validations you want to skip *explicit* (they get the :if => :extracted? condition) instead of just skipping them entirely when needed.
--Matt Jones