Skip to content

Instantly share code, notes, and snippets.

@yellow5
Created November 10, 2011 13:31
Show Gist options
  • Save yellow5/1354854 to your computer and use it in GitHub Desktop.
Save yellow5/1354854 to your computer and use it in GitHub Desktop.
Examples using foreigner and foreigner-matcher
class ForeignKeyMigration < ActiveRecord::Migration
def up
add_foreign_key :user_logins, :users, :dependent => :delete
end
def down
drop_foreign_key :user_logins, :users
end
end
[1] http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
* Referential Action Options*
The primary reference documentation [1] shows us three ways we can use foreign keys:
Delete child records upon deletion of a parent record (CASCADE)
Set foreign keys to NULL when deleting a parent record (SET NULL)
Prevent parent record deletion with a foreign key in child records (RESTRICTED, NO ACTION)
Notes...
The CASCADE option can be mimicked in Rails, giving us the option of managing deletion
on database level or the application level.
* Option Examples *
These are meant to be examples and descriptions of what would/could happen should we use
the given option on existing data.
CASCADE
children.parent_id -> parent.id
If we delete a given parent record, it will in turn delete any children tied to it.
SET NULL
children.parent_id -> parent.id
If we delete a given parent record, it will in turn set child parent_id values to NULL.
This would allow us to keep the children record intact and remove an orphan reference.
RESTRICTED, NO ACTION
children.parent_id -> parent.id
We have the ability do delete a given children record, but we cannot delete a parent record
that has children tied to it. This would force us to delete all child records before we delete
the parent record. On the application level, this can be accomplished via cascade deletion.
class User < ActiveRecord::Base
has_many :user_logins
end
class UserLogin < ActiveRecord::Base
belongs_to :user
end
require 'spec_helper'
describe UserLogin do
# Mysql foreign keys require an index on the column that the constraint is applied to.
# Foreigner will create it if it's not there, however a good habit is to do it yourself.
# It's always better to know as much about the schema as possible!
#
# Note the attributes and indexes contexts use the format of remarkable.
context 'attributes' do
it { should have_column(:user_id, :type => :integer) }
end
context 'indexes' do
it { should have_index(:user_id) }
end
context 'foreign keys' do
it { should have_foreign_key_for(:user, :dependent => :delete) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment