Order of Validation for Associated Models

I have an Account Model. It has a polymorphic association to an
Address model. The Address model validates on what you’d expect, and
the the issue comes about in the order of models and validations.

We are trying to wedge functionality into an existing design without
breaking a large system. The new requirement is that the address is
only validated if a boolean column (is_admin_account) is false.

Where I’m running into issue is that the Address model validates
before the values are updated in the Account model and, based on the
bool value, I want to validate or not.

The application uses InheritedResources, but I completely over-rode
the create and update functions to bypass this with the same result.
I’m not sure exactly where to dig into this. I considered a custom
validation function, but don’t want to pitch the standard validations
that exist (and work with the biz rules as they stand).

Anyone have a good place for me to start?

Thanks in advance!

Ray P. wrote in post #966033:

I have an Account Model. It has a polymorphic association to an
Address model. The Address model validates on what you’d expect, and
the the issue comes about in the order of models and validations.

We are trying to wedge functionality into an existing design without
breaking a large system.

How’s your test coverage? If it’s decent, you shouldn’t need to worry
about breaking the system, or about “wedging in” functionality.

(The idea of “wedging in” functionality is itself scary. If something
is worth doing, it’s usually worth doing right, with all the refactoring
that that implies.)

The new requirement is that the address is
only validated if a boolean column (is_admin_account) is false.

And which table is that field in?

(Style note: it’s more Rubyish to leave the “is_” off the names of
booleans.)

Where I’m running into issue is that the Address model validates
before the values are updated in the Account model and, based on the
bool value, I want to validate or not.

So you want to validate the address, or not, depending on the contents
of a field in an associated record in a different table? That sounds
really, really smelly to me. I suspect it might be worth moving the
validation flag into the addresses table.

If you can explain more about the structure of your data, I can probably
be more helpful.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On 3 December 2010 20:51, Ray P. [email protected]
wrote:

Where I’m running into issue is that the Address model validates
before the values are updated in the Account model and, based on the
bool value, I want to validate or not.

I’m not sure what you mean by “the Address model validates before the
values are updated in the Account model” - can you extract some model
code to illustrate?

Anyone have a good place for me to start?

It occurs to me, that if an Address can be different depending on the
model it’s associated with, the validation check needs to move to the
associated model maybe. How about adding something like this to
Account:

validates :valid_address if :address

private
def valid_address
errors.add_to_base “address is not valid for one reason or
another” unless address.valid_for_account
end

… and this to Address:

def valid_for_account
return true if self.post_code.nil?
return true if self.some_other_validation_check_returns_true
return true if self.etc
end

You could merge the Errors from Address into Account, rather than just
adding a generic one to base, to display “nice” messages to the user.
http://dev.rubyonrails.org/attachment/ticket/11394/merge_bang_errors.patch

We’ve scrapped the validations on Address in the project as it wasn’t
important to the biz model. Here’s some sudo-code (good pun?)

Account--------------------------------------------------------------
class Account < ActiveRecord::Base
has_one :address, :as => :addressable, :dependent => :destroy
accepts_nested_attributes_for :address
end

Address


class Address < ActiveRecord::Base
belongs_to :addressable, :polymorphic => true

validates_presence_of :street_address, :city, :state, :postal_code, :if
=> :should_validate?

def should_validate?
# Admittedly lame, but trying not to upset an existing house of
cards.
# Here the Account fields have not been updated yet when updating,
but are set on a new instance of Account.
# If validations are removed from this class (Address), the
address doesn’t fail and then the Account records updates and saves
# as normal.
addressable.respond_to?(:is_admin_account) ?
addressable.is_admin_account? : false
end
end

So, what it seems from my observation is that the Address model gets
validated before the Account fields are set. I checked and this is
true for all fields, not just the one that I’m checking. It seems
kind of odd for this to be a default behavior, no?

Your solution, below, is what I was trying to work around as I wasn’t
able to get a hold of the client and was trying to leave things as I
found them. Like I was telling Marnen, this isn’t my design; I’ve
been hired in to work on an existing application. Woe be to he that
wrote this thing if I ever catch him in a dark alley – you should see
what I have to work with!

Because a language allows you to do things doesn’t make them right =)

I agree, but there are a couple of issues with that. One is that the
flag would be so deep and obscured from the actual function of it that
it would be most magical. The flag is already one level deeper than
I’d prefer it to be. My design chops are pretty fair and this is the
best dress we can put on the pig. Second is that this database is not
my design, nor the application, and with 1000’s of lines of code that
go in some pretty intense reporting, changing the structure in a way
that would satisfy the client’s request elegantly would far outstrip
any budget that is allotted for the current iteration. If you’d
really like a rundown on the problem and our solution we can share
screens on Skype and I’ll convince you that the solution is the
cleanest, given budget and requirement. Though application design
isn’t really the question.

The ‘is’ prefix and its ilk for a bool field or function has been
working for me for 20 years and around 9 languages. I love Ruby and
Rails, but given that wisdom is having the experience to recognize a
mistake as you’re about to make it again, I’ll reserve the right to
adopt what is arguably better and ignore that which is not.

That said, and a bit exhausted from defending the irrelevant…how’s
'bout that question?