Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
John Crepezzi committed Jan 15, 2011
0 parents commit 98c24ee
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
@@ -0,0 +1,4 @@
*.swp
*.swo
*.gem
.bundle
29 changes: 29 additions & 0 deletions README.md
@@ -0,0 +1,29 @@
## DatabaseValidation

We write a lot of validations in our ActiveRecord models that already exist inside of our database. This gem seeks to automatically create those validations.

### Usage

class Thing < ActiveRecord::Base
include DatabaseValidation
end

### What's automatically created

For now:

* validates_uniquness_of (with scope)
* validates_presence_of
* validates_length_of :maximum

In the future:

* all associations

### Installation

gem 'database_validation'

### Author

John Crepezzi <john.crepezzi@gmail.com>
25 changes: 25 additions & 0 deletions Rakefile
@@ -0,0 +1,25 @@
require 'spec/rake/spectask'
require File.dirname(__FILE__) + '/lib/database_validation/version'

task :build do
system "gem build database_validation.gemspec"
end

task :release => :build do
# tag and push
system "git tag v#{DatabaseValidation::version}"
system "git push origin --tags"
# push the gem
system "gem push database_validation-#{DatabaseValidation::version}.gem"
end

Spec::Rake::SpecTask.new(:test) do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
fail_on_error = true # be explicit
end

Spec::Rake::SpecTask.new(:rcov) do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
t.rcov = true
fail_on_error = true # be explicit
end
18 changes: 18 additions & 0 deletions database_validation.gemspec
@@ -0,0 +1,18 @@
require File.dirname(__FILE__) + '/lib/database_validation/version'

spec = Gem::Specification.new do |s|
s.name = 'database_validation'
s.author = 'John Crepezzi'
s.add_development_dependency('rspec')
s.description = 'Automatically pull validations out of your database and apply them to your models'
s.email = 'john.crepezzi@gmail.com'
s.files = Dir['lib/**/*.rb']
s.homepage = 'http://seejohnrun.github.com/database_validation/'
s.platform = Gem::Platform::RUBY
s.require_paths = ['lib']
s.summary = 'Automatic Rails validations from your database'
s.test_files = Dir.glob('spec/*.rb')
s.version = DatabaseValidation::version
s.rubyforge_project = "database_validation"
end

28 changes: 28 additions & 0 deletions lib/database_validation.rb
@@ -0,0 +1,28 @@
require 'active_record'

module DatabaseValidation

def self.included(base)
@base = base
Detector.detect_validations(@base)
end

# tested with 'mysql' and 'mysql2' adapters
module Detector

def self.detect_validations(base)
base.columns.each do |field|
next if field.name == base.primary_key # don't add validations here
allow_nil = field.null
base.send(:validates_length_of, field.name.to_sym, :maximum => field.limit, :allow_nil => allow_nil)
base.send(:validates_presence_of, field.name.to_sym, :allow_nil => allow_nil) unless allow_nil
end
ActiveRecord::Base.connection.indexes(base.table_name).each do |key|
col_syms = key.columns.map(&:to_sym)
base.send(:validates_uniqueness_of, col_syms.first.to_sym, :scope => col_syms.slice(1, -1)) if key.unique
end
end

end

end
11 changes: 11 additions & 0 deletions lib/database_validation/version.rb
@@ -0,0 +1,11 @@
module DatabaseValidation

def self.version
VERSION.join('.')
end

private

VERSION = [0, 0, 1]

end
25 changes: 25 additions & 0 deletions spec/examples/validates_length_of_spec.rb
@@ -0,0 +1,25 @@
require File.dirname(__FILE__) + '/../spec_helper'

describe DatabaseValidation do

before(:all) do
execute 'create table length1s (id int(11) auto_increment primary key, name varchar(10))'
end

before(:all) do
class Length1 < ActiveRecord::Base
include DatabaseValidation
end
end

after(:all) do
execute 'drop table length1s'
end

it 'should be able to automatically detect validations' do
lambda do
Length1.create!(:name => 'this name is too long')
end.should raise_error(ActiveRecord::RecordInvalid)
end

end
25 changes: 25 additions & 0 deletions spec/examples/validates_presence_of_spec.rb
@@ -0,0 +1,25 @@
require File.dirname(__FILE__) + '/../spec_helper'

describe DatabaseValidation do

before(:all) do
execute 'create table presence1s (id int(11) auto_increment primary key, name varchar(10) NOT NULL)'
end

before(:all) do
class Presence1 < ActiveRecord::Base
include DatabaseValidation
end
end

after(:all) do
execute 'drop table presence1s'
end

it 'should be automatically able to detect null validations' do
lambda do
Presence1.create!
end.should raise_error(ActiveRecord::RecordInvalid)
end

end
28 changes: 28 additions & 0 deletions spec/examples/validates_uniqueness_of_spec.rb
@@ -0,0 +1,28 @@
require File.dirname(__FILE__) + '/../spec_helper'

describe DatabaseValidation do

before(:all) do
execute 'create table unique1s (id int(11) auto_increment primary key, name varchar(10))'
execute 'create unique index name_unique on unique1s (name)'
end

before(:all) do
class Unique1 < ActiveRecord::Base
include DatabaseValidation
end
end

after(:all) do
execute 'drop table unique1s'
end

it 'should not allow two of the same record when validates_uniqueness_of is around' do
Unique1.create!(:name => 'john')
lambda do
Unique1.create!(:name => 'john')
end.should raise_error(ActiveRecord::RecordInvalid)
end

end

7 changes: 7 additions & 0 deletions spec/spec_helper.rb
@@ -0,0 +1,7 @@
require File.dirname(__FILE__) + '/../lib/database_validation'

ActiveRecord::Base.establish_connection(:adapter => 'mysql', :database => 'johnsql')

def execute(sql)
ActiveRecord::Base.connection.execute(sql)
end

0 comments on commit 98c24ee

Please sign in to comment.