Is this dry? (models & migrations)

I’m creating a tool for a preexisting distributed SQL database. One
of the things I’m doing is taking an SQL dump of the schema and
transforming it into models. It strikes me that there appears to be a
lot of duplication between the model and the database.
– Unique keys are defined both in the model (validates_uniqueness_of)
and in the database (ALTER TABLE [dbo].[data] ADD CONSTRAINT UNIQUE
( [name], [deleteDate] ) ON [PRIMARY]).
– Relations are defined in both the model (belongs_to) and in the
database (ALTER TABLE [dbo].[data] ADD CONSTRAINT FOREIGN KEY
( [checkOutSuerID] ) REFERENCES [dbo].[users] ( [userID]) NOT FOR
REPLICATION)
– Null allowances are defined both in the model
(validates_exclusion_of :column, :in => [nil]) and in the database
( [column] [varchar] (21) NOT NULL)

This doesn’t seem very dry. I’m wondering what’s going on.

Also, I’m wondering if I should be adding field size limits to my
models as well. If so, does this also go for fields which are the
default size ([varchar] (255))?

On 8/31/07, Student [email protected] wrote:

( [checkOutSuerID] ) REFERENCES [dbo].[users] ( [userID]) NOT FOR
REPLICATION)
– Null allowances are defined both in the model
(validates_exclusion_of :column, :in => [nil]) and in the database
( [column] [varchar] (21) NOT NULL)

This doesn’t seem very dry. I’m wondering what’s going on.

There’s some discussion about this in the Agile Web D. With
Rails book. Some people prefer to include integrity constraints in
the database as well as in Rails, and some people will rely solely on
Rails to maintain the integrity of the database by model validations.
The latter has the advantage of being database agnostic as well as
keeping all of your logic where it should be - in the model.

Also, I’m wondering if I should be adding field size limits to my
models as well. If so, does this also go for fields which are the
default size ([varchar] (255))?

it depends… Do you want users to be able to enter as much information
into a field as they want, only to have the result (unknowingly to
them) truncated? Or do you want to enforce a constraint on the number
of letters they enter, receiving an error message if they go past this
value?

Adam

I’ve only gone through the book once, and this is my first project, so
I must have forgotten/missed what was there. The index didn’t help
much :frowning:

I am wondering about whether or not I need the model to enforce this
information or if I can rely on the adapter to throw when the db
refuses to do a save. (Note that in my case, the db already has the
information.) It’s not clear to me that there is much of a
difference. You seem to be implying that an attempt to write an
overly-large string will silently truncate in the db? (Uggh) Does
RoR require an explicit size check when the size is the default?

Of course, if this were the development list, I would be wondering why
RoR cannot read all of this stuff from the db & stick it into the
model the same way that it does the column names & types. :slight_smile:

Nathan

Rails is of the opinion that constraints such as these belong in the
application layer. While you can certainly use database-level
constraints to enforce your business rules at the level of the
database (and some would argue that you should in any case), rails
will work best if you specify them in the model. Trying to generate
human readable errors from exceptions thrown from constraints in the
database, for instance, doesn’t work very well in practice so I would
suggest that you continue to use your validations and other
application-level constraints, DRY or not.

Rein

On 8/31/07, Student [email protected] wrote:

I’ve only gone through the book once, and this is my first project, so
I must have forgotten/missed what was there. The index didn’t help
much :frowning:

now that I have the book in front of me, there isn’t a large section
discussing this, it was actually in a small footnote on page 141 where
Dave talks about some developers not bothering with database defined
foreign key constraints while he personally prefers to use them.

I am wondering about whether or not I need the model to enforce this
information or if I can rely on the adapter to throw when the db
refuses to do a save. (Note that in my case, the db already has the
information.)

If you rely only on the database to throw an exception when a
constraint is violated, how will you filter this down to your rails
app? You’ll have to make sure you catch any exceptions (which of
course you should be doing anyways), determine what exception was
raised and then display the appropriate error. Wouldn’t it be easier
to simply use rails’ built in validations to handle this, and use
error_messages_for to display the messages to the user? (and have the
database constraints in place to offer you further protection in the
event that you write some bad code)

It’s not clear to me that there is much of a
difference.

like I mentioned in my previous post, using Rails to enforce data
integrity is database agnostic and it keeps all your logic in the
model. If another programmer were to work on your application, they’d
be able to quickly see all the validations directly from within Rails,
whereas if you relied solely on the database, they’d have to go
searching in another place to find this information. Plus, you gain a
bunch of convenience methods when using Rails’ built in validations.

You seem to be implying that an attempt to write an
overly-large string will silently truncate in the db? (Uggh) Does
RoR require an explicit size check when the size is the default?

yes, the data will be silently truncated and rails does need an
explicit size check to prevent this from happening (or at least to
prevent the record from being saved if the field is over a certain
number of characters)

Of course, if this were the development list, I would be wondering why
RoR cannot read all of this stuff from the db & stick it into the
model the same way that it does the column names & types. :slight_smile:

Here’s a plugin which may be of use to you:

http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/

Adam

rein.henrichs wrote:

Rails is of the opinion that constraints such as these belong in the
application layer.

Rails is of the opinion that you can add (and make) plugins to
synchronize
database and program validations. DrySQL leaps to mind…

And note that each database constraint is typically a unique index, so
this
might optimize all the excessive re-queries that ActiveRecord runs on
all
the constrained tables at .save time…


Phlip
http://www.oreilly.com/catalog/9780596510657/
“Test Driven Ajax (on Rails)”
assert_xpath, assert_javascript, & assert_ajax

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs