Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 676
Jason Swett Avatar asked Jan 05 '11 22:01

Jason Swett


People also ask

How does foreign key work in Rails?

In Rails 5, adding foreign key constraints was added to have the database protect the integrity of associated data. Once a foreign key constraint is defined, your database will not allow you to remove records that are required by other tables.

What is foreign key in Ruby on Rails?

A foreign key is a field in one database that uniquely identifies a row in another table. For this example, our foreign key in the expenses table will identify which category each expense should fall under.

How do I add a foreign key in Ruby on Rails?

If you want you can always use add_index on the fields that you want as foreign keys. Or you can write your migrations in SQL or perhaps even force rails to do the foreign keys somehow. But the thing is you won't even look for a way to do it if you don't know rails is not doing itin the first place.

What is the difference between Has_one and Belongs_to?

They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user . To determine who "has" the other object, look at where the foreign key is.


2 Answers

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
like image 141
Omar Qureshi Avatar answered Oct 23 '22 22:10

Omar Qureshi


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

like image 20
Heikki Avatar answered Oct 23 '22 22:10

Heikki