Skip to content
This repository


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Database constraints made easy for ActiveRecord.

branch: master
Octocat-spinner-32 lib * fixed Mysql2Adapter for Rails 3.1 August 14, 2013
Octocat-spinner-32 spec Removed RR mocking library. August 19, 2013
Octocat-spinner-32 .gitignore Ignore Gemfile.lock. August 10, 2012
Octocat-spinner-32 .rspec Cleanups. September 25, 2011
Octocat-spinner-32 Gemfile Cleanups. September 25, 2011
Octocat-spinner-32 LICENSE [ADDED] Gemspec. August 28, 2010
Octocat-spinner-32 Update December 12, 2012
Octocat-spinner-32 Rakefile Cleanups. September 25, 2011
Octocat-spinner-32 rein.gemspec Merge pull request #10 from webhoernchen/master August 18, 2013


Database constraints made easy for ActiveRecord. Rein currently supports PostgreSQL and MySQL (foreign keys only) for both Rails 2 & 3.


Database integrity is a "good thing". Constraining the allowed values in your database at the database-level (rather than solely at the application-level) is a much more robust way of ensuring your data stays sane.

Unfortunately, ActiveRecord doesn't encourage (or even allow) you to use database integrity without resorting to hand-crafted SQL. Rein adds a handful of methods to your ActiveRecord migrations so that you can easily tame your database.


How is Rein different to other gems like foreigner or redhillonrails, which do the same thing?

If you're using MySQL then there is no difference, Rein should work as a drop-in replacement. If you're using PostgreSQL however, then Rein provides you with extra methods for placing check constraints on your data.

If DHH wanted my app to have database constraints then Rails would have been born with them?

Rails is an opinionated piece of software. One opinion is that your database should simply function as a "dumb" container which your application controls. This is the opinion of Rails.

Another opinion is that your database is actually a powerful DBMS which has already solved problems like data integrity, and your application should wield this power.

Quick Start

Install the gem:

gem install rein

Add a foreign key constraint:

add_foreign_key_constraint :books, :authors

Add a numericality constraint (PostgreSQL only):

add_numericality_constraint :books, :publication_month, :greater_than_or_equal_to => 1, :less_than_or_equal_to => 12

Add an inclusion constraint (PostgreSQL only):

add_inclusion_constraint :books, :state, :in => %w(available on_loan)


Let's look at constraining values for this simple library application.

Here we have a table of authors:

create_table :authors do |t|
  t.string :name, :null => false


And here we have a table of books:

create_table :books do |t|
  t.belongs_to :author,          :null => false
  t.string     :name,            :null => false
  t.string     :state,           :null => false
  t.integer    :published_year,  :null => false
  t.integer    :published_month, :null => false


# A book should always belong to an author.
# The database should prevent us from deleteing an author who has books.
add_foreign_key_constraint :books, :authors, :on_delete => :restrict

# Our library doesn't deal in classics.
add_numericality_constraint :books, :published_year, :greater_than => 1980

# Month is always between 1 and 12.
add_numericality_constraint :books, :published_month, :greater_than_or_equal_to => 1, :less_than_or_equal_to => 12

# State is always either "available" or "on_loan".
add_inclusion_constraint :books, :state, :in => %w(available on_loan)


Something went wrong with that request. Please try again.