valle 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.travis.yml +7 -0
- data/Gemfile +13 -0
- data/Guardfile +10 -0
- data/LICENSE +22 -0
- data/README.md +70 -0
- data/Rakefile +19 -0
- data/features/adds_validators.feature +48 -0
- data/features/step_definitions/rails_steps.rb +7 -0
- data/features/support/env.rb +7 -0
- data/lib/valle/bound_mapper.rb +36 -0
- data/lib/valle/bounds_manager.rb +26 -0
- data/lib/valle/configuration.rb +26 -0
- data/lib/valle/engine.rb +4 -0
- data/lib/valle/hooks.rb +19 -0
- data/lib/valle/railtie.rb +7 -0
- data/lib/valle/validation_setter.rb +20 -0
- data/lib/valle/version.rb +3 -0
- data/lib/valle.rb +27 -0
- data/test/lib/bound_mapper_test.rb +21 -0
- data/test/test_helper.rb +7 -0
- data/valle.gemspec +20 -0
- metadata +112 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'minitest', test_folders: "test" do
|
5
|
+
# with Minitest::Unit
|
6
|
+
watch(%r|^test/(.*)\/?test_(.*)\.rb|)
|
7
|
+
watch(%r|^test/(.*)\/?(.*)_test\.rb|)
|
8
|
+
watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
|
9
|
+
watch(%r|^test/test_helper\.rb|) { "test" }
|
10
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Anton Kalyaev
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Valle [](http://travis-ci.org/kaize/valle) [](https://codeclimate.com/github/kaize/valle)
|
2
|
+
|
3
|
+
Valle adds validators to all the fields of your ActiveRecord models,
|
4
|
+
so you should not think that string length or ID value exceeds the permissible limits.
|
5
|
+
|
6
|
+
For example, maximum length of the string in PostgreSQL is 255. We will
|
7
|
+
setup the following validator for you, so you don't need to write it by
|
8
|
+
hands.
|
9
|
+
|
10
|
+
validates :field_name, length: { maximum: 255 }
|
11
|
+
|
12
|
+
Note: If you do not do this (and usually you are) and try to enter 2147483648 into the field with type: `interger` (see [Numeric types](http://www.postgresql.org/docs/9.2/static/datatype-numeric.html) section of PostgreSQL docs), you will get 500 error.
|
13
|
+
|
14
|
+
Example:
|
15
|
+
|
16
|
+
PG::Error: ERROR: value "2147483648" is out of range for type integer
|
17
|
+
: SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1
|
18
|
+
|
19
|
+
There is a simular gem, called [validates_lengths_from_database](http://github.com/rubiety/validates_lengths_from_database). It solves only one part -
|
20
|
+
applicable to strings. This gem is designed to work with all possible field types.
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
gem 'valle'
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
$ bundle
|
31
|
+
|
32
|
+
Or install it yourself as:
|
33
|
+
|
34
|
+
$ gem install valle
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
By default, this gem adds validators to all your ActiveRecord models.
|
39
|
+
This means that, basically, you don't need to tweak it.
|
40
|
+
|
41
|
+
However, you could tell him directly what models it should take into account by adding `config/initializers/valle.rb`:
|
42
|
+
|
43
|
+
Valle.configure do |config|
|
44
|
+
config.models = %w(User, Post)
|
45
|
+
end
|
46
|
+
|
47
|
+
Also, you should be able to turn it off temporary by setting `enabled` option to `false`.
|
48
|
+
|
49
|
+
Valle.configure do |config|
|
50
|
+
config.enabled = false
|
51
|
+
end
|
52
|
+
|
53
|
+
## Contributing
|
54
|
+
|
55
|
+
1. Fork it
|
56
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
57
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
58
|
+
4. Run test suite (`rake test_suite`)
|
59
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
60
|
+
6. Create new Pull Request
|
61
|
+
|
62
|
+
## Core team
|
63
|
+
|
64
|
+
- [Anton Kalyaev](http://github.com/akalyaev)
|
65
|
+
- [Andrew Kulakov](http://github.com/Andrew8xx8)
|
66
|
+
- [Alexander Kirillov](http://github.com/saratovsource)
|
67
|
+
|
68
|
+
## License
|
69
|
+
|
70
|
+
Valle is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'cucumber/rake/task'
|
5
|
+
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.test_files = FileList['test/lib/*_test.rb']
|
9
|
+
t.verbose = true
|
10
|
+
end
|
11
|
+
|
12
|
+
Cucumber::Rake::Task.new(:cucumber) do |t|
|
13
|
+
t.fork = true
|
14
|
+
t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'progress')]
|
15
|
+
end
|
16
|
+
|
17
|
+
task test_suite: [:test, :cucumber]
|
18
|
+
|
19
|
+
task default: :test_suite
|
@@ -0,0 +1,48 @@
|
|
1
|
+
Feature: adds validators
|
2
|
+
Background:
|
3
|
+
When I successfully run `bundle exec rails new testapp`
|
4
|
+
And I cd to "testapp"
|
5
|
+
And I add "factory_girl_rails" as a dependency
|
6
|
+
And I add "valle" from this project as a dependency
|
7
|
+
When I successfully run `bundle install`
|
8
|
+
And I write to "db/migrate/1_create_users.rb" with:
|
9
|
+
"""
|
10
|
+
class CreateUsers < ActiveRecord::Migration
|
11
|
+
def self.up
|
12
|
+
create_table :users do |t|
|
13
|
+
t.string :name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
"""
|
18
|
+
When I successfully run `bundle exec rake db:migrate --trace`
|
19
|
+
And I write to "app/models/user.rb" with:
|
20
|
+
"""
|
21
|
+
class User < ActiveRecord::Base
|
22
|
+
end
|
23
|
+
"""
|
24
|
+
|
25
|
+
@disable-bundler
|
26
|
+
Scenario: generate a rails 3 application and use factory definitions
|
27
|
+
When I write to "test/factories.rb" with:
|
28
|
+
"""
|
29
|
+
FactoryGirl.define do
|
30
|
+
factory :user do
|
31
|
+
name "John"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
"""
|
35
|
+
When I write to "test/unit/user_test.rb" with:
|
36
|
+
"""
|
37
|
+
require 'test_helper'
|
38
|
+
|
39
|
+
class UserTest < ActiveSupport::TestCase
|
40
|
+
test "should not save user when name is too long" do
|
41
|
+
user = FactoryGirl.create(:user)
|
42
|
+
user.name = 'a' * 256
|
43
|
+
assert !user.save
|
44
|
+
end
|
45
|
+
end
|
46
|
+
"""
|
47
|
+
When I successfully run `bundle exec rake test --trace`
|
48
|
+
Then the output should contain "1 tests, 1 assertions, 0 failures, 0 errors"
|
@@ -0,0 +1,7 @@
|
|
1
|
+
When /^I add "([^"]+)" from this project as a dependency$/ do |gem_name|
|
2
|
+
append_to_file('Gemfile', %{gem "#{gem_name}", :path => "#{PROJECT_ROOT}"\n})
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I add "([^"]+)" as a dependency$/ do |gem_name|
|
6
|
+
append_to_file('Gemfile', %{gem "#{gem_name}"\n})
|
7
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Valle
|
2
|
+
|
3
|
+
Bound = Struct.new :minimum, :maximum
|
4
|
+
|
5
|
+
class BoundMapper
|
6
|
+
|
7
|
+
##
|
8
|
+
# Returns a new bound for the column
|
9
|
+
#
|
10
|
+
# @param [Column] column the column
|
11
|
+
#
|
12
|
+
def bound(column)
|
13
|
+
Bound.new minimum(column), maximum(column)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
##
|
19
|
+
# Get the lower limit for a given column
|
20
|
+
#
|
21
|
+
# @param [Column] column the column
|
22
|
+
#
|
23
|
+
def minimum(column)
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Get the upper limit for a given column
|
29
|
+
#
|
30
|
+
# @param [Column] column the column
|
31
|
+
#
|
32
|
+
def maximum(column)
|
33
|
+
column.limit
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Valle
|
2
|
+
class BoundsManager
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
##
|
7
|
+
# Add validators for all columns of a given class
|
8
|
+
#
|
9
|
+
# 2 steps:
|
10
|
+
# 1) get bound for the column
|
11
|
+
# 2) set validation
|
12
|
+
#
|
13
|
+
# @param [ActiveRecord::Base] klass the AR model class
|
14
|
+
#
|
15
|
+
def add_validators(klass)
|
16
|
+
mapper = BoundMapper.new
|
17
|
+
|
18
|
+
columns = klass.columns
|
19
|
+
columns.each do |column|
|
20
|
+
bound = mapper.bound(column)
|
21
|
+
ValidationSetter.add_validator(bound, column, klass)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# TODO [AK 09/12/12] maybe we should use ActiveSupport::Configurable ?
|
2
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
3
|
+
|
4
|
+
module Valle
|
5
|
+
module Configuration
|
6
|
+
|
7
|
+
mattr_accessor :options
|
8
|
+
|
9
|
+
self.options = {
|
10
|
+
enabled: true, # gem is enabled by default
|
11
|
+
models: nil # nil means to select all the AR models
|
12
|
+
}
|
13
|
+
|
14
|
+
def configure
|
15
|
+
yield self
|
16
|
+
end
|
17
|
+
|
18
|
+
def enabled=(value)
|
19
|
+
self.options[:enabled] = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def models=(collection)
|
23
|
+
self.options[:models] = collection
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/valle/engine.rb
ADDED
data/lib/valle/hooks.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Valle
|
2
|
+
class Hooks
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def init
|
7
|
+
ActiveSupport.on_load(:active_record) do
|
8
|
+
ActiveRecord::Base.class_eval do
|
9
|
+
# TODO [AK 09/12/12] possible we should run it after the class was inherited
|
10
|
+
# @see http://stackoverflow.com/q/7093992/820520
|
11
|
+
def self.inherited(subclass)
|
12
|
+
Valle::BoundsManager.add_validators(subclass)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Valle
|
2
|
+
class ValidationSetter
|
3
|
+
class << self
|
4
|
+
|
5
|
+
##
|
6
|
+
# Adds validator to the klass column depending on its type
|
7
|
+
#
|
8
|
+
# @param [Bound] bound the bound
|
9
|
+
# @param [Column] column the column
|
10
|
+
# @param [ActiveRecord::Base] klass the AR model class
|
11
|
+
#
|
12
|
+
def add_validator(bound, column, klass)
|
13
|
+
case column.type
|
14
|
+
when :string
|
15
|
+
klass.validates column.name, length: { maximum: bound.maximum }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/valle.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'valle/configuration'
|
2
|
+
|
3
|
+
module Valle
|
4
|
+
extend Configuration
|
5
|
+
|
6
|
+
# core
|
7
|
+
autoload :BoundMapper, 'valle/bound_mapper'
|
8
|
+
autoload :BoundsManager, 'valle/bounds_manager'
|
9
|
+
autoload :ValidationSetter, 'valle/validation_setter'
|
10
|
+
|
11
|
+
# hooks
|
12
|
+
autoload :Hooks, 'valle/hooks'
|
13
|
+
end
|
14
|
+
|
15
|
+
# load Rails/Railtie
|
16
|
+
begin
|
17
|
+
require 'rails'
|
18
|
+
rescue LoadError
|
19
|
+
#do nothing
|
20
|
+
end
|
21
|
+
|
22
|
+
# if not using Railtie, call `Valle::Hooks.init` directly
|
23
|
+
# TODO [AK 09/12/12] move this block to initializers
|
24
|
+
if defined? Rails
|
25
|
+
require 'valle/railtie'
|
26
|
+
require 'valle/engine'
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "active_record"
|
3
|
+
|
4
|
+
class BoundMapperTest < TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@bound_mapper = Valle::BoundMapper.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_should_return_bound
|
11
|
+
column = ::ActiveRecord::ConnectionAdapters::Column.new("test_column", "")
|
12
|
+
assert @bound_mapper.bound(column), "Bound for column '#{column.name}' not found"
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_return_maximum_for_column_with_type_string
|
16
|
+
column = ::ActiveRecord::ConnectionAdapters::Column.new("test_column", "", "string(255)")
|
17
|
+
bound = @bound_mapper.bound(column)
|
18
|
+
|
19
|
+
assert_equal 255, bound.maximum
|
20
|
+
end
|
21
|
+
end
|
data/test/test_helper.rb
ADDED
data/valle.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/valle/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Anton Kalyaev"]
|
6
|
+
gem.email = ["anton.kalyaev@gmail.com"]
|
7
|
+
gem.description = %q{Valle adds validators to all the fields of your ActiveRecord models, so you should not think that string length or ID value exceeds the permissible limits}
|
8
|
+
gem.summary = %q{Set automatically the minimum and maximum values for your ActiveRecord model fields}
|
9
|
+
gem.homepage = "http://github.com/kaize/valle"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "valle"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Valle::VERSION
|
17
|
+
|
18
|
+
gem.add_runtime_dependency 'activerecord'
|
19
|
+
gem.add_runtime_dependency 'activesupport'
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: valle
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Anton Kalyaev
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activesupport
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Valle adds validators to all the fields of your ActiveRecord models,
|
47
|
+
so you should not think that string length or ID value exceeds the permissible limits
|
48
|
+
email:
|
49
|
+
- anton.kalyaev@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- .travis.yml
|
56
|
+
- Gemfile
|
57
|
+
- Guardfile
|
58
|
+
- LICENSE
|
59
|
+
- README.md
|
60
|
+
- Rakefile
|
61
|
+
- features/adds_validators.feature
|
62
|
+
- features/step_definitions/rails_steps.rb
|
63
|
+
- features/support/env.rb
|
64
|
+
- lib/valle.rb
|
65
|
+
- lib/valle/bound_mapper.rb
|
66
|
+
- lib/valle/bounds_manager.rb
|
67
|
+
- lib/valle/configuration.rb
|
68
|
+
- lib/valle/engine.rb
|
69
|
+
- lib/valle/hooks.rb
|
70
|
+
- lib/valle/railtie.rb
|
71
|
+
- lib/valle/validation_setter.rb
|
72
|
+
- lib/valle/version.rb
|
73
|
+
- test/lib/bound_mapper_test.rb
|
74
|
+
- test/test_helper.rb
|
75
|
+
- valle.gemspec
|
76
|
+
homepage: http://github.com/kaize/valle
|
77
|
+
licenses: []
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
hash: -1528972839465003213
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
hash: -1528972839465003213
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 1.8.24
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Set automatically the minimum and maximum values for your ActiveRecord model
|
106
|
+
fields
|
107
|
+
test_files:
|
108
|
+
- features/adds_validators.feature
|
109
|
+
- features/step_definitions/rails_steps.rb
|
110
|
+
- features/support/env.rb
|
111
|
+
- test/lib/bound_mapper_test.rb
|
112
|
+
- test/test_helper.rb
|