validates_existence 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rails2/validator.rb +40 -0
- data/lib/rails3/validator.rb +54 -0
- data/lib/validates_existence.rb +11 -52
- data/{init.rb → rails/init.rb} +0 -0
- data/test/models/name.rb +3 -0
- data/test/models/user.rb +7 -0
- data/test/models/user_with_allow_nil.rb +9 -0
- data/test/models/user_with_poly.rb +9 -0
- data/test/models/user_with_poly_allow_nil.rb +9 -0
- data/test/test_helper.rb +22 -0
- data/test/validates_existence_test.rb +57 -0
- metadata +23 -8
@@ -0,0 +1,40 @@
|
|
1
|
+
module Perfectline
|
2
|
+
module ValidatesExistence
|
3
|
+
|
4
|
+
def validates_existence_of(*attr_names)
|
5
|
+
configuration = {:message => "does not exist", :on => :save}
|
6
|
+
configuration.update(attr_names.extract_options!.symbolize_keys)
|
7
|
+
|
8
|
+
send(validation_method(configuration[:on] || :save), configuration) do |record|
|
9
|
+
|
10
|
+
attr_names.each do |attr|
|
11
|
+
association = reflect_on_association(attr.to_s.sub(/_id$/, '').to_sym)
|
12
|
+
|
13
|
+
if association.nil? || association.macro != :belongs_to
|
14
|
+
raise ArgumentError, "Can not validate existence on #{attribute}, not a belongs_to association."
|
15
|
+
end
|
16
|
+
|
17
|
+
value = record.__send__(association.primary_key_name)
|
18
|
+
next if value.nil? && configuration[:allow_nil]
|
19
|
+
|
20
|
+
if association.options.has_key?(:foreign_type)
|
21
|
+
foreign_type = record.__send__(association.options[:foreign_type])
|
22
|
+
|
23
|
+
if not foreign_type.blank?
|
24
|
+
association_class = foreign_type.constantize
|
25
|
+
else
|
26
|
+
record.errors.add(attr, :existence, :default => configuration[:message]) and next
|
27
|
+
end
|
28
|
+
else
|
29
|
+
association_class = association.klass
|
30
|
+
end
|
31
|
+
|
32
|
+
unless association_class.exists?(value)
|
33
|
+
record.errors.add(attr, :existence, :default => configuration[:message])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Perfectline
|
2
|
+
module ValidatesExistence
|
3
|
+
|
4
|
+
module InstanceMethods
|
5
|
+
class ExistenceValidator < ActiveModel::EachValidator
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
# set the default message if its unspecified
|
9
|
+
options[:message] ||= :existence
|
10
|
+
super(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate_each(record, attribute, value)
|
14
|
+
normalized = attribute.to_s.sub(/_id$/, "").to_sym
|
15
|
+
association = record.class.reflect_on_association(normalized)
|
16
|
+
|
17
|
+
if association.nil? or !association.belongs_to?
|
18
|
+
raise ArgumentError, "Cannot validate existence on #{normalized}, not a :belongs_to association"
|
19
|
+
end
|
20
|
+
|
21
|
+
target_class = nil
|
22
|
+
|
23
|
+
# dealing with polymorphic belongs_to
|
24
|
+
if association.options.has_key?(:foreign_type)
|
25
|
+
foreign_type = record.__send__(association.options.fetch(:foreign_type))
|
26
|
+
target_class = foreign_type.constantize unless foreign_type.nil?
|
27
|
+
else
|
28
|
+
target_class = association.klass
|
29
|
+
end
|
30
|
+
|
31
|
+
if target_class.nil? or !target_class.exists?(value)
|
32
|
+
record.errors.add(attribute, options[:message], :default => "does not exist")
|
33
|
+
|
34
|
+
# add the error on both :relation and :relation_id
|
35
|
+
if options[:both]
|
36
|
+
normalized = attribute.to_s.ends_with?("_id") ? normalized : "#{attribute}_id"
|
37
|
+
record.errors.add(normalized, options[:message], :default => "does not exist")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module ClassMethods
|
46
|
+
|
47
|
+
def validates_existence_of(*attr_names)
|
48
|
+
validates_with ExistenceValidator, _merge_attributes(attr_names)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
data/lib/validates_existence.rb
CHANGED
@@ -1,52 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
configuration = {:message => "does not exist", :on => :save}
|
13
|
-
configuration.update(attr_names.extract_options!.symbolize_keys)
|
14
|
-
|
15
|
-
send(validation_method(configuration[:on] || :save), configuration) do |record|
|
16
|
-
|
17
|
-
attr_names.each do |attr|
|
18
|
-
attribute = attr.to_s.sub(/_id$/, '').to_sym
|
19
|
-
association = reflect_on_association(attribute)
|
20
|
-
|
21
|
-
if association.nil? || association.macro != :belongs_to
|
22
|
-
raise ArgumentError, "Can not validate existence on #{attribute}, not a belongs_to association."
|
23
|
-
end
|
24
|
-
|
25
|
-
value = record.__send__(association.primary_key_name)
|
26
|
-
next if value.nil? && configuration[:allow_nil]
|
27
|
-
|
28
|
-
if association.options.has_key?(:foreign_type)
|
29
|
-
foreign_type = record.__send__(association.options[:foreign_type])
|
30
|
-
|
31
|
-
if not foreign_type.blank?
|
32
|
-
association_class = foreign_type.constantize
|
33
|
-
else
|
34
|
-
record.errors.add(attr, configuration[:message]) and next
|
35
|
-
end
|
36
|
-
else
|
37
|
-
association_class = association.klass
|
38
|
-
end
|
39
|
-
|
40
|
-
unless association_class.exists?(value)
|
41
|
-
record.errors.add(attr, :existence, :default => configuration[:message])
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
ActiveRecord::Base.send(:include, Perfectline::Validations::ValidatesExistence)
|
1
|
+
if Rails::VERSION::MAJOR >= 3
|
2
|
+
require "active_model"
|
3
|
+
require "rails3/validator"
|
4
|
+
|
5
|
+
ActiveModel::Validations.__send__(:include, Perfectline::ValidatesExistence::InstanceMethods)
|
6
|
+
ActiveModel::Validations.__send__(:extend, Perfectline::ValidatesExistence::ClassMethods)
|
7
|
+
else
|
8
|
+
require "rails2/validator"
|
9
|
+
|
10
|
+
ActiveRecord::Base.__send__(:extend, Perfectline::ValidatesExistence)
|
11
|
+
end
|
data/{init.rb → rails/init.rb}
RENAMED
File without changes
|
data/test/models/name.rb
ADDED
data/test/models/user.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 2'
|
4
|
+
|
5
|
+
require 'sqlite3'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'active_record'
|
8
|
+
require 'active_record/base'
|
9
|
+
|
10
|
+
ActiveRecord::Migration.verbose = false
|
11
|
+
ActiveRecord::Base.establish_connection(
|
12
|
+
"adapter" => "sqlite3",
|
13
|
+
"database" => ":memory:"
|
14
|
+
)
|
15
|
+
|
16
|
+
require File.join(File.dirname(__FILE__), '..', 'rails', 'init.rb')
|
17
|
+
|
18
|
+
autoload :Name, File.join(File.dirname(__FILE__), 'models', 'name.rb')
|
19
|
+
autoload :User, File.join(File.dirname(__FILE__), 'models', 'user.rb')
|
20
|
+
autoload :UserWithAllowNil, File.join(File.dirname(__FILE__), 'models', 'user_with_allow_nil.rb')
|
21
|
+
autoload :UserWithPoly, File.join(File.dirname(__FILE__), 'models', 'user_with_poly.rb')
|
22
|
+
autoload :UserWithPolyAllowNil, File.join(File.dirname(__FILE__), 'models', 'user_with_poly_allow_nil.rb')
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
|
+
|
3
|
+
class TestValidatesExistence < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
ActiveRecord::Schema.define(:version => 1) do
|
7
|
+
|
8
|
+
create_table :names, :force => true do |t|
|
9
|
+
t.column :name, :string
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table :users, :force => true do |t|
|
13
|
+
t.references :name
|
14
|
+
t.references :relation, :polymorphic => true
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
ActiveRecord::Base.connection.drop_table(:users)
|
22
|
+
ActiveRecord::Base.connection.drop_table(:names)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_save_with_no_relation
|
26
|
+
assert_equal User.new.save, false
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_save_with_relation
|
30
|
+
name = Name.create(:name => "foo")
|
31
|
+
assert_equal User.new(:name => name).save, true
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_save_with_bogus_id
|
35
|
+
assert_equal User.new(:name_id => 100).save, false
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_allow_nil
|
39
|
+
assert_equal UserWithAllowNil.new.save, true
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_poly_relation
|
43
|
+
assert_equal UserWithPoly.new.save, false
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_poly_relation_with_name
|
47
|
+
name = Name.create(:name => "bar")
|
48
|
+
assert_equal UserWithPoly.new(:relation => name).save, true
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_poly_relation_with_allow_nil
|
52
|
+
assert_equal UserWithPolyAllowNil.new.save, true
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validates_existence
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Tanel Suurhans
|
@@ -10,7 +15,7 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date:
|
18
|
+
date: 2010-04-14 00:00:00 +03:00
|
14
19
|
default_executable:
|
15
20
|
dependencies: []
|
16
21
|
|
@@ -26,9 +31,11 @@ extra_rdoc_files:
|
|
26
31
|
- README.markdown
|
27
32
|
files:
|
28
33
|
- README.markdown
|
29
|
-
- init.rb
|
30
34
|
- install.rb
|
35
|
+
- lib/rails2/validator.rb
|
36
|
+
- lib/rails3/validator.rb
|
31
37
|
- lib/validates_existence.rb
|
38
|
+
- rails/init.rb
|
32
39
|
has_rdoc: true
|
33
40
|
homepage: http://github.com/perfectline/validates_existence/tree/master
|
34
41
|
licenses: []
|
@@ -42,20 +49,28 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
49
|
requirements:
|
43
50
|
- - ">="
|
44
51
|
- !ruby/object:Gem::Version
|
52
|
+
segments:
|
53
|
+
- 0
|
45
54
|
version: "0"
|
46
|
-
version:
|
47
55
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
56
|
requirements:
|
49
57
|
- - ">="
|
50
58
|
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
51
61
|
version: "0"
|
52
|
-
version:
|
53
62
|
requirements: []
|
54
63
|
|
55
64
|
rubyforge_project:
|
56
|
-
rubygems_version: 1.3.
|
65
|
+
rubygems_version: 1.3.6
|
57
66
|
signing_key:
|
58
67
|
specification_version: 3
|
59
68
|
summary: Validates Rails model belongs_to association existence.
|
60
|
-
test_files:
|
61
|
-
|
69
|
+
test_files:
|
70
|
+
- test/models/name.rb
|
71
|
+
- test/models/user.rb
|
72
|
+
- test/models/user_with_allow_nil.rb
|
73
|
+
- test/models/user_with_poly.rb
|
74
|
+
- test/models/user_with_poly_allow_nil.rb
|
75
|
+
- test/test_helper.rb
|
76
|
+
- test/validates_existence_test.rb
|