activerecord-database_validations 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5fe2382415d03dd7e2f8b7006bb505d7da55e42a
4
+ data.tar.gz: 4e6a436ce619c8ef1c79d3c98f7ac970d6020c9d
5
+ SHA512:
6
+ metadata.gz: 0e4cdca4c51a1b083e72708fb908bfb01edb31fcb0e70017b511d4f0f5bd63a50d5970be1b075714a4a31a9a497c14c0e37a9d026f5d88d4830dbb310df24a45
7
+ data.tar.gz: bc7b4ccbe3525ed20a4a4d931d37fcf0a1adb8d045fd47d65166f0674da7e7655a82911d997b226cd1ea7f735e53570c9a19ecda6c1607fd1056ae96ff415d95
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in activerecord-database_validations.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # ActiveRecord::DatabaseValidations [![Gem Version](https://badge.fury.io/rb/activerecord-database_validations.svg)](http://badge.fury.io/rb/activerecord-database_validations)
2
+
3
+ An ActiveRecord extension that lets you use your database validations.
4
+
5
+ * Converts `ActiveRecord::StatementInvalid` related to database validations on
6
+ `ActiveRecord::Base#save` into a validation error.
7
+ * Quickly add pre-save validations according to your database validations.
8
+
9
+ Currently supports mysql and postgresql. Feel free to [help support
10
+ more](#extend-database-support).
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'activerecord-database_validations'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install activerecord-database_validations
27
+
28
+ ## Usage
29
+
30
+ This extension is included into `ActiveRecord::Base` automatically, so all you
31
+ need to do is use it.
32
+
33
+
34
+ ### Pre-save validation
35
+
36
+ ```ruby
37
+ # == Schema Information
38
+ #
39
+ # Table name: users
40
+ #
41
+ # id :integer not null, primary key
42
+ # username :string not null
43
+ # group_id :integer
44
+ # inviter_id :integer
45
+ #
46
+ # Indexes
47
+ #
48
+ # index_boards_on_group_id_and_username (group_id,username) UNIQUE
49
+ #
50
+ # Foreign Keys
51
+ #
52
+ # add_foreign_key "users", "users", column: "inviter_id"
53
+ #
54
+
55
+ class User < ActiveRecord::Base
56
+ validates_database
57
+ # This is an alias to (which can be used separately):
58
+ # validates_database_not_null
59
+ # validates_database_unique
60
+ # validates_database_foreign_key
61
+ end
62
+
63
+ # validates_database_not_null
64
+ u = User.new
65
+ u.valid?
66
+ => false
67
+ u.errors.messages
68
+ => { :username => ["can't be blank"] }
69
+
70
+ # validates_database_unique
71
+ u1 = User.new(group_id: 5, username: "somename")
72
+ u1.save
73
+ => true
74
+ u2 = User.new(group_id: 5, username: "somename")
75
+ u2.save
76
+ => false
77
+ u2.errors.messages
78
+ => { :username => ["has already been taken"] }
79
+
80
+ # validates_database_foreign_key
81
+ u1 = User.new(username: "anothername", inviter_id: -1)
82
+ u1.save
83
+ => false
84
+ u1.errors.messages
85
+ => { inviter_id: ["is not included in the list"] }
86
+ ```
87
+
88
+ As mentioned above you can use a specific validation type, and any of these
89
+ `validates_database*` methods can also receive the `:message` option (and
90
+ sometimes other validation options depending on the back-end used to preform
91
+ the actual validation).
92
+
93
+ ### On-save validation
94
+
95
+ You don't really have to do anything but specify the right validations in your
96
+ schema (or migrations). On knows database validation errors
97
+ `ActiveRecord::Base#save` will return false, `ActiveRecord::Base#save!` will
98
+ raise an `ActiveRecord::RecordInvalid`, and `ActiveRecord::Base#errors` will
99
+ show the error on the specific field.
100
+
101
+ ### On-save vs pre-save validations
102
+
103
+ * Pre-save does not handle race conditions (`::validates_database_unique` and
104
+ `::validates_database_foreign_key`). This is the actual reason behind using
105
+ database validations. So between the time the check was made and the time the
106
+ record was saved:
107
+ * There could be an extra record that would make the new record fail the
108
+ unique validation.
109
+ * The referenced record could have been deleted that would make the foreign
110
+ key validation fail.
111
+ * On-save only happens if the application validations succeeded. This means you
112
+ will not see the error on the failing field (in `ActiveRecord::Base#errors`).
113
+ That said, it will also only show one error, so if two database validations
114
+ failed only one field will show an error.
115
+ * Pre-save does an extra query for `::validates_database_unique` and
116
+ `::validates_database_foreign_key`, so if time is of the essence let the
117
+ on-save validation catch the error, otherwise it's best to add
118
+ the full `::validates_database` to your model.
119
+
120
+ ## Notes
121
+
122
+ * You do not have any control over on-save validations, the logic is applied if
123
+ you want it or not on every ActiveRecord::Base. If you can think of a reason
124
+ why it shouldn't, please file an
125
+ [issue](https://github.com/odedniv/activerecord-database_validations/issues).
126
+ * When the unique index is on multiple columns mysql and postgresql (and maybe
127
+ others) do not fail if any of the columns is nil. With this in mind, the
128
+ error is added on the last column of the index.
129
+
130
+ ## Development
131
+
132
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
133
+
134
+ ## Contributing
135
+
136
+ 1. Fork it (https://github.com/odedniv/activerecord-database_validations/fork )
137
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
138
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
139
+ 4. Push to the branch (`git push origin my-new-feature`)
140
+ 5. Create a new Pull Request
141
+
142
+ ### Extend database support
143
+
144
+ This consists of 3 simple steps:
145
+
146
+ 1. Add an adapter gem as a development dependency in
147
+ `activerecord-database_validations.gemspec`.
148
+ 2. Add adapter configuration to `spec/db/adapters.rb`.
149
+ 3. Add new patterns for error matching in
150
+ `lib/activerecord/database_validations/rescues.rb`.
151
+
152
+ Of course make sure `rspec` doesn't fail, and create a new Pull Request!
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ namespace :db do
4
+ desc "Prepare databases for testing"
5
+ task :prepare do
6
+ require "active_record"
7
+ require File.expand_path("../spec/db/adapters.rb", __FILE__)
8
+ DATABASE_ADAPTERS.each do |database_adapter_config|
9
+ ActiveRecord::Base.establish_connection(database_adapter_config)
10
+ load File.expand_path("../spec/db/schema.rb", __FILE__)
11
+ end
12
+ end
13
+ end
data/UNLICENSE ADDED
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
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 NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'activerecord/database_validations/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "activerecord-database_validations"
8
+ spec.version = ActiveRecord::DatabaseValidations::VERSION
9
+ spec.authors = ["Oded Niv"]
10
+ spec.email = ["oded.niv@gmail.com"]
11
+
12
+ spec.summary = %q{Handle database validations}
13
+ spec.description = %q{Use database validations and convert ActiveRecord::StatementInvalid into ActiveRecord::RecordInvalid}
14
+ spec.homepage = "https://github.com/odedniv/activerecord-database_validations"
15
+ spec.license = "UNLICENSE"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_runtime_dependency "activerecord", "~> 4.2", ">= 4.2.0"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.8"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "byebug", "~> 3.5"
27
+ spec.add_development_dependency "rspec", "~> 3.2"
28
+ spec.add_development_dependency "simplecov", "~> 0.9"
29
+ spec.add_development_dependency "database_cleaner", "~> 1.4"
30
+
31
+ spec.add_development_dependency "mysql2", "~> 0.3"
32
+ spec.add_development_dependency "pg", "~> 0.18"
33
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "activerecord/database_validations"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ rake db:prepare
@@ -0,0 +1,9 @@
1
+ require "active_record"
2
+ require "activerecord/database_validations/version"
3
+
4
+ module ActiveRecord::DatabaseValidations
5
+ end
6
+
7
+ require "activerecord/database_validations/memoization"
8
+ require "activerecord/database_validations/rescues"
9
+ require "activerecord/database_validations/validations"
@@ -0,0 +1,11 @@
1
+ module ActiveRecord::DatabaseValidations::Memoization
2
+ def indexes
3
+ @indexes ||= connection.indexes(table_name)
4
+ end
5
+
6
+ def foreign_keys
7
+ @foreign_keys ||= connection.foreign_keys(table_name)
8
+ end
9
+ end
10
+
11
+ ActiveRecord::Base.extend ActiveRecord::DatabaseValidations::Memoization
@@ -0,0 +1,88 @@
1
+ module ActiveRecord::DatabaseValidations::Rescues
2
+ def self.included(base)
3
+ base.around_save :rescue_database_not_null
4
+ base.around_save :rescue_database_unique
5
+ base.around_save :rescue_database_foreign_key
6
+ end
7
+
8
+ NOT_NULL_PATTERNS = [
9
+ /^Mysql2::Error: Column '(.+?)' cannot be null:/,
10
+ /^Mysql2::Error: Field '(.+?)' doesn't have a default value:/,
11
+ /^PG::NotNullViolation: ERROR: null value in column "(.+?)" violates not-null constraint\nDETAIL:/,
12
+ ]
13
+ def rescue_database_not_null
14
+ begin
15
+ yield
16
+ rescue ActiveRecord::StatementInvalid => e
17
+ if NOT_NULL_PATTERNS.any? { |p| e.message =~ p }
18
+ column_name = $1
19
+ errors.add(column_name, :blank)
20
+ raise ActiveRecord::RecordInvalid.new(self)
21
+ else
22
+ raise
23
+ end
24
+ end
25
+ end
26
+
27
+ UNIQUE_PATTERNS_BY_COLUMN = [
28
+ /^PG::UniqueViolation: ERROR: duplicate key value violates unique constraint ".+?"\nDETAIL: Key \((?:.+?, )*(.+?)\)=\(.+?\) already exists\./,
29
+ ]
30
+ UNIQUE_PATTERNS_BY_INDEX = [
31
+ /^Mysql2::Error: Duplicate entry '.+?' for key '(.+?)':/,
32
+ ]
33
+ PRIMARY_INDEXES = [
34
+ 'PRIMARY',
35
+ ]
36
+ def rescue_database_unique
37
+ self.class.indexes if UNIQUE_PATTERNS_BY_INDEX.any? # load the indexes not inside a failed transaction (eg. PG::InFailedSqlTransaction)
38
+ begin
39
+ yield
40
+ rescue ActiveRecord::RecordNotUnique => e
41
+ column_name = if UNIQUE_PATTERNS_BY_COLUMN.any? { |p| e.message =~ p }
42
+ $1
43
+ elsif UNIQUE_PATTERNS_BY_INDEX.any? { |p| e.message =~ p }
44
+ if PRIMARY_INDEXES.include?($1)
45
+ self.class.primary_key
46
+ else
47
+ index = self.class.indexes.find { |i| i.name == $1 }
48
+ raise if index.nil?
49
+ index.columns[-1]
50
+ end
51
+ else
52
+ raise
53
+ end
54
+ errors.add(column_name, :taken)
55
+ raise ActiveRecord::RecordInvalid.new(self)
56
+ end
57
+ end
58
+
59
+
60
+ FOREIGN_KEY_PATTERNS_BY_COLUMN = [
61
+ /^Mysql2::Error: Cannot add or update a child row: a foreign key constraint fails \(`.+?`\.`.+?`, CONSTRAINT `.+?` FOREIGN KEY \(`(.+?)`\) REFERENCES `.+?` \(`.+?`\)\):/,
62
+ /^PG::ForeignKeyViolation: ERROR: insert or update on table ".+?" violates foreign key constraint ".+?"\nDETAIL: Key \((.+?)\)=\(.+?\) is not present in table ".+?"\.\n:/,
63
+ ]
64
+ FOREIGN_KEY_PATTERNS_BY_FOREIGN_KEY = [
65
+ ]
66
+ def rescue_database_foreign_key
67
+ self.class.foreign_keys if FOREIGN_KEY_PATTERNS_BY_FOREIGN_KEY.any? # load he foreign keys not inside a failing transaction (eg. PG::InFailedSqlTransaction)
68
+ begin
69
+ yield
70
+ rescue ActiveRecord::InvalidForeignKey => e
71
+ column_name = if FOREIGN_KEY_PATTERNS_BY_COLUMN.any? { |p| e.message =~ p }
72
+ $1
73
+ elsif FOREIGN_KEY_PATTERNS_BY_FOREIGN_KEY.any? { |p| e.message =~ p }
74
+ foreign_key = self.class.foreign_keys.find { |i| i.name == $1 }
75
+ raise if foreign_key.nil?
76
+ foreign_key.column
77
+ else
78
+ raise
79
+ end
80
+ errors.add(column_name, :inclusion)
81
+ raise ActiveRecord::RecordInvalid.new(self)
82
+ end
83
+ end
84
+ end
85
+
86
+ class ActiveRecord::Base
87
+ include ActiveRecord::DatabaseValidations::Rescues
88
+ end
@@ -0,0 +1,45 @@
1
+ module ActiveRecord::DatabaseValidations::Validations
2
+ def validates_database
3
+ validates_database_not_null
4
+ validates_database_unique
5
+ validates_database_foreign_key
6
+ end
7
+
8
+ def validates_database_not_null(options = {})
9
+ columns.reject(&:null).each do |column|
10
+ validation = proc do
11
+ if self[column.name].nil?
12
+ errors.add(column.name, options[:message] || :blank)
13
+ end
14
+ end
15
+
16
+ if column.extra == 'auto_increment'
17
+ validate(on: :update, &validation)
18
+ else
19
+ validate(&validation)
20
+ end
21
+ end
22
+ end
23
+
24
+ def validates_database_unique(options = {})
25
+ validates_uniqueness_of(primary_key, **options, allow_nil: true) if primary_key
26
+ indexes.select(&:unique).each do |index|
27
+ validates_uniqueness_of(index.columns[-1], **options, scope: index.columns[0...-1], if: -> { index.columns.none? { |c| self[c].nil? } })
28
+ end
29
+ end
30
+
31
+ def validates_database_foreign_key(options = {})
32
+ foreign_keys.each do |foreign_key|
33
+ model = Class.new(ActiveRecord::Base) do
34
+ self.table_name = foreign_key.to_table
35
+ end
36
+ validate do
37
+ if not self[foreign_key.column].nil? and not model.where(foreign_key.primary_key => self[foreign_key.column]).exists?
38
+ errors.add(foreign_key.column, options[:message] || :inclusion)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ ActiveRecord::Base.extend ActiveRecord::DatabaseValidations::Validations
@@ -0,0 +1,5 @@
1
+ module ActiveRecord
2
+ module DatabaseValidations
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,192 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-database_validations
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Oded Niv
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-03-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 4.2.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '4.2'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 4.2.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.8'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.8'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '10.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: byebug
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.5'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.5'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.2'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.2'
89
+ - !ruby/object:Gem::Dependency
90
+ name: simplecov
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.9'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.9'
103
+ - !ruby/object:Gem::Dependency
104
+ name: database_cleaner
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.4'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.4'
117
+ - !ruby/object:Gem::Dependency
118
+ name: mysql2
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.3'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.3'
131
+ - !ruby/object:Gem::Dependency
132
+ name: pg
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '0.18'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '0.18'
145
+ description: Use database validations and convert ActiveRecord::StatementInvalid into
146
+ ActiveRecord::RecordInvalid
147
+ email:
148
+ - oded.niv@gmail.com
149
+ executables: []
150
+ extensions: []
151
+ extra_rdoc_files: []
152
+ files:
153
+ - ".gitignore"
154
+ - ".rspec"
155
+ - ".travis.yml"
156
+ - Gemfile
157
+ - README.md
158
+ - Rakefile
159
+ - UNLICENSE
160
+ - activerecord-database_validations.gemspec
161
+ - bin/console
162
+ - bin/setup
163
+ - lib/activerecord/database_validations.rb
164
+ - lib/activerecord/database_validations/memoization.rb
165
+ - lib/activerecord/database_validations/rescues.rb
166
+ - lib/activerecord/database_validations/validations.rb
167
+ - lib/activerecord/database_validations/version.rb
168
+ homepage: https://github.com/odedniv/activerecord-database_validations
169
+ licenses:
170
+ - UNLICENSE
171
+ metadata: {}
172
+ post_install_message:
173
+ rdoc_options: []
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ requirements: []
187
+ rubyforge_project:
188
+ rubygems_version: 2.4.5
189
+ signing_key:
190
+ specification_version: 4
191
+ summary: Handle database validations
192
+ test_files: []