If you’re on PostgreSQL and see the importance of data-layer constraints – this gem/plugin is for you. It integrates constraints into PostgreSQL adapter so you can add/remove them in your migrations. You get two simple methods for adding/removing constraints, as well as a pack of pre-made constraints.
The repository is at http://github.com/maxim/sexy_pg_constraints
Install
As a gem
or as a plugin
Usage
Say you have a table "books" and you want your Postgres DB to ensure that their title is not-blank, alphanumeric, and its length is between 3 and 50 chars. You also want to make sure that their isbn is unique. In addition you want to blacklist a few isbn numbers from ever being in your database. You can tell all that to your Postgres in no time. Generate a migration and write the following.
def self.up
constrain :books do |t|
t.title :not_blank => true, :alphanumeric => true, :length_within => 3..50
t.isbn :unique => true, :blacklist => %w(badbook1 badbook2)
end
end
def self.down
deconstrain :books do |t|
t.title :not_blank, :alphanumeric, :length_within
t.isbn :unique, :blacklist
end
end
end
This will add all the necessary constraints to the database on the next migration, and remove them on rollback.
There’s also a syntax for when you don’t need to work with multiple columns at once.
The above line works exactly the same as this block
t.title :not_blank => true, :length_within => 3..50
end
Same applies to deconstrain.
Available constraints
Below is the list of constraints available and tested so far.
- whitelist
- blacklist
- not_blank
- within
- length_within
- alphanumeric
- positive
- unique
- exact_length
Extensibility
All constraints are located in the lib/constraints.rb. Extending this module with more methods will automatically make constraints available in migrations. All methods in the Constraints module are under module_function directive. Each method is supposed to return a piece of SQL that is inserted "alter table foo add constraint bar #{RIGHT HERE};."