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.
@@ -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
@@ -1,52 +1,11 @@
1
- module Perfectline
2
- module Validations
3
- module ValidatesExistence
4
-
5
- def self.included(base)
6
- base.send(:extend, ClassMethods)
7
- end
8
-
9
- module ClassMethods
10
-
11
- def validates_existence_of(*attr_names)
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
File without changes
@@ -0,0 +1,3 @@
1
+ class Name < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,7 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ belongs_to :name
4
+
5
+ validates_existence_of :name
6
+
7
+ end
@@ -0,0 +1,9 @@
1
+ class UserWithAllowNil < ActiveRecord::Base
2
+
3
+ self.table_name = "users"
4
+
5
+ belongs_to :name
6
+
7
+ validates_existence_of :name, :allow_nil => true
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ class UserWithPoly < ActiveRecord::Base
2
+
3
+ self.table_name = "users"
4
+
5
+ belongs_to :relation, :polymorphic => true
6
+
7
+ validates_existence_of :relation
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ class UserWithPolyAllowNil < ActiveRecord::Base
2
+
3
+ self.table_name = "users"
4
+
5
+ belongs_to :relation, :polymorphic => true
6
+
7
+ validates_existence_of :relation, :allow_nil => true
8
+
9
+ end
@@ -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
- version: 0.3.2
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: 2009-11-20 00:00:00 +02:00
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.5
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