SchemaValidations

Overview

One of the great things about Rails (ActiveRecord, in particular) is that it inspects the database and automatically defines accessors for all your columns, keeping your model class definitions simple and DRY. That's great for simple data columns, but where it falls down is when your table contains constraints.

create_table :users do |t|
  t.string :email, :null => false, :limit => 30
  t.boolean :confirmed, :null => false
end

In that case :null => false, :limit => 30 and :boolean must be covered on the model level.

class User < ActiveRecord::Base
  validates :email, :presence => true, :length => 30
  validates :confirmed, :presence => true, :inclusion => { :in => [true, false] }
end

…which isn't the most DRY approach.

SchemaValidations aims to cover that and does boring work for you. It inspect the database and automatically creates validations basing on the schema. After installing it your model is as simple as it can be.

class User < ActiveRecord::Base
end

Validations are there but they are created by schema_validations under the hood.

Installation

Simply add schema_validations to your Gemfile.

gem "schema_validations"

What if I want something special?

SchemaValidations is highly customizable. You can configure behavior globally via SchemaValidations.setup or per-model via SchemaValidations::ActiveRecord::schema_validations, such as:

class User < ActiveRecord::Base
  schema_validations :except => :email
  validates :email, :presence => true, :length => { :in => 5..30 }
end

See SchemaValidations::Config for the available options.

Which validations are covered?

Constraints:

|      Constraint     |                     Validation                           |
|---------------------|----------------------------------------------------------|
| :null => false      | validates ... :presence => true                          |
| :limit => 100       | validates ... :length => { :maximum => 100 }             |
| :unique => true     | validates ... :uniqueness => true                        |

Data types:

|         Type       |                      Validation                           |
|--------------------|-----------------------------------------------------------|
| :boolean           | :validates ... :inclusion => { :in => [true, false] }     |
| :float             | :validates ... :numericality => true                      |
| :integer           | :validates ... :numericality => { :only_integer => true } |

Dependency

SchemaValidations uses the schema_plus gem for its schema queries. That gem will by default auto-create foreign key constraints that you probably want – but if you don't want them, you can disable them using schema_plus config.

Compatibility

SchemaValidations supports all combinations of:

  • rails 3.0 or 3.1

  • MRI ruby 1.8.7 or 1.9.2

How do I know what it did?

If you're curious (or dubious) about what validations SchemaValidations defines, you can check the log file. For every assocation that SchemaValidations defines, it generates an info entry such as

[schema_validations] Article.validates_length_of :title, :allow_nil=>true, :maximum=>50

which shows the exact validation definition call.

SchemaValidations defines the validations lazily, only creating them when a record of the class is first accessed. So you may need to search through the log file for “schema_validations” to find them all (and some may not be defined at all if they were never needed for the logged use case).

I don't use constraints

TODO and blame you

History

  • SchemaValidations is derived from the “Red Hill On Rails” plugin schema_validations originally created by harukizaemon (github.com/harukizaemon)

  • SchemaValidations was created in 2011 by Michał Łomnicki and Ronen Barzel

Testing

SchemaValidations is tested using rspec, sqlite3, and rvm, with some hackery to test against multiple versions of rails and ruby. To run the full combo of tests, after you've forked & cloned:

$ cd schema_validations
$ ./runspecs --install  # do this once to install gem dependencies for all versions (slow)
$ ./runspecs # as many times as you like

You can also pick a specific version of rails and ruby to use, such as:

$ rvm use 1.9.2
$ export SCHEMA_VALIDATIONS_RAILS_VERSION=3.1
$ bundle update --local rails
$ rake spec

If you're running ruby 1.9.2, code coverage results will be in coverage/index.html – it should be at 100% coverage.

License

This gem is released under the MIT license.