Jason Swett
Jason Swett

Reputation: 45074

Foreign keys in Rails 3

I understand that according to Rails philosophy, data integrity checks should be done at the application level as opposed to the database level. Like many other developers, I enthusiastically disagree.

I've found a lot of discussions addressing this problem but they all seem to be old and, dismayingly, they seem to point to divergent solutions.

I have to imagine there's a de-facto standard way of doing foreign key constraints in Rails 3. However, whatever it is (if it does exist) seems to be smothered by all the past discussions because I can't find it.

Are Rails developers by this point mostly on the same page with foreign keys? If so, I would love to know how they're generally handled.

Upvotes: 11

Views: 3728

Answers (3)

Adam Spiers
Adam Spiers

Reputation: 17916

I found myself asking the same question the other day, so I did some research and collated my findings in an answer to an older but similar Stack Overflow question. I hope that's of use.

BTW, when you say that you "enthusiastically disagree" that data integrity checks should be done at the application level as opposed to the database level, I assume you mean that they should be done at both levels, rather than just at the database. I hope I'm right in thinking that virtually everyone agrees that having integrity checks at the application level is a Good Thing, and that the only topic being debated is whether they should additionally be done in the database.

Upvotes: 0

Omar Qureshi
Omar Qureshi

Reputation: 9093

It is for this reason that I (and the people who wrote Enterprise Rails - http://oreilly.com/catalog/9780596515201) recommend that you write your entire up and down migrations in SQL.

The advantages are:

  • The ability to add foreign keys on table creation - without a separate alter table
  • It allows you to use database specific field types - like tsvectors
  • It allows you to add different types of indexes - like Gin or Gist
  • It allows you to write functions and/or triggers
  • You wont have to remember what DSL type relates to what SQL field type - e.g. :number

There are disadvantages:

  • It's not database agnostic (who cares and how often will you change your database?)
  • It's not Ruby (but every good Rails developer should know SQL, right?)

But, overall I reckon the advantages outweigh the disadvantages.

Quick example:

  def self.up
    execute <<EOS

create table .... (
  ....
);

EOS
   end

Upvotes: 6

Heikki
Heikki

Reputation: 15417

http://guides.rubyonrails.org/migrations.html#active-record-and-referential-integrity

"Although Active Record does not provide any tools for working directly with such features, the execute method can be used to execute arbitrary SQL. There are also a number of plugins such as foreign_key_migrations which add foreign key support to Active Record."

Upvotes: 1

Related Questions