Phil Darnowsky writes:
> One example: we have a User model, which usually must have an email
> address--but under certain circumstances, a User without an email can be
> valid. Similarly, we have mobile numbers on our Users (we do stuff with
> SMS), and that's usually not required, but sometimes it is.
>
> It's pretty easy, then, for the validation code for a model to turn into
> a big mess of special cases and conditionals. Hard to write, hard to
> test, hard to understand, easy to write bugs.
FWIW, one way of dealing with this sort of situation is using
single-table-inheritance, which lets you associate more than one Ruby
class (say, BasicUser, AdminUser, etc.) with the rows of a single
table (say, "users"). The subclasses can then have their own
validations.
There are cases that get awkward here, one of which I've actually
illustrated already: if you ever want to upgrade a BasicUser to be
an admin without altering references to that particular "users" row
from elsewhere in the schema, STI forces you to jump through some
really awkward hoops. But if your problem domain is such that you're
pretty sure that won't happen (e.g., a "book" won't *ever* magically
transform itself into a "dvd", even though they're both in the
"merchandise" table), then it can be a pretty nice fit.
(It also separates the validation rules from the mechanics of
implementing the UI --- which means that if you've got multiple
controllers manipulating the same data, you don't have to worry about
whether they're all implementing the same set of rules.)
rst