Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 98c24eef5c2299ce81e74629ad6894d0cc5a5d37 0 parents
John Crepezzi authored
4 .gitignore
@@ -0,0 +1,4 @@
+*.swp
+*.swo
+*.gem
+.bundle
29 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 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 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 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 lib/database_validation/version.rb
@@ -0,0 +1,11 @@
+module DatabaseValidation
+
+ def self.version
+ VERSION.join('.')
+ end
+
+ private
+
+ VERSION = [0, 0, 1]
+
+end
25 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 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 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 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
Please sign in to comment.
Something went wrong with that request. Please try again.