# Is this dry? (models & migrations)

**URL:** <https://www.ruby-forum.com/t/is-this-dry-models-migrations/113486>\
**Category:** Rails\
**Created:** [August 31, 2007, 4:25pm UTC](https://www.ruby-forum.com/t/is-this-dry-models-migrations/113486 "2007-08-31T16:25:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![student](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@student](https://www.ruby-forum.com/u/student)\
**Post date:** [August 31, 2007, 4:25pm UTC](https://www.ruby-forum.com/t/is-this-dry-models-migrations/113486/1 "2007-08-31T16:25:58Z")

</div>

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))?

---

<div class="post-metadata">

**Author:** ![student](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@student](https://www.ruby-forum.com/u/student)\
**Post date:** [August 31, 2007, 4:51pm UTC](https://www.ruby-forum.com/t/is-this-dry-models-migrations/113486/2 "2007-08-31T16:51:01Z")

</div>

On 8/31/07, Student [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![student](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@student](https://www.ruby-forum.com/u/student)\
**Post date:** [August 31, 2007, 4:57pm UTC](https://www.ruby-forum.com/t/is-this-dry-models-migrations/113486/3 "2007-08-31T16:57:02Z")

</div>

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 ☹

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. 🙂

Nathan

---

<div class="post-metadata">

**Author:** ![student](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@student](https://www.ruby-forum.com/u/student)\
**Post date:** [September 1, 2007, 4:21pm UTC](https://www.ruby-forum.com/t/is-this-dry-models-migrations/113486/4 "2007-09-01T16:21:14Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![student](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@student](https://www.ruby-forum.com/u/student)\
**Post date:** [August 31, 2007, 6:18pm UTC](https://www.ruby-forum.com/t/is-this-dry-models-migrations/113486/5 "2007-08-31T18:18:11Z")

</div>

On 8/31/07, Student [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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 ☹

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. 🙂

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

[http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/](http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/)

Adam

---

<div class="post-metadata">

**Author:** ![student](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@student](https://www.ruby-forum.com/u/student)\
**Post date:** [September 1, 2007, 5:39pm UTC](https://www.ruby-forum.com/t/is-this-dry-models-migrations/113486/6 "2007-09-01T17:39:24Z")

</div>

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/](http://www.oreilly.com/catalog/9780596510657/)  
“Test Driven Ajax (on Rails)”  
assert\_xpath, assert\_javascript, & assert\_ajax
