mongomatic 0.1.31 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. data/README.rdoc +90 -26
  2. data/lib/mongomatic.rb +1 -2
  3. data/lib/mongomatic/base.rb +14 -2
  4. data/lib/mongomatic/errors.rb +7 -0
  5. data/test/helper.rb +4 -1
  6. metadata +4 -25
  7. data/lib/mongomatic/validatable.rb +0 -31
  8. data/lib/mongomatic/validatable/child_validation.rb +0 -17
  9. data/lib/mongomatic/validatable/errors.rb +0 -108
  10. data/lib/mongomatic/validatable/included_validation.rb +0 -11
  11. data/lib/mongomatic/validatable/macros.rb +0 -316
  12. data/lib/mongomatic/validatable/object_extension.rb +0 -21
  13. data/lib/mongomatic/validatable/requireable.rb +0 -28
  14. data/lib/mongomatic/validatable/understandable.rb +0 -33
  15. data/lib/mongomatic/validatable/validatable_class_methods.rb +0 -89
  16. data/lib/mongomatic/validatable/validatable_instance_methods.rb +0 -111
  17. data/lib/mongomatic/validatable/validations/validates_acceptance_of.rb +0 -16
  18. data/lib/mongomatic/validatable/validations/validates_associated.rb +0 -15
  19. data/lib/mongomatic/validatable/validations/validates_confirmation_of.rb +0 -25
  20. data/lib/mongomatic/validatable/validations/validates_each.rb +0 -16
  21. data/lib/mongomatic/validatable/validations/validates_exclusion_of.rb +0 -19
  22. data/lib/mongomatic/validatable/validations/validates_format_of.rb +0 -18
  23. data/lib/mongomatic/validatable/validations/validates_inclusion_of.rb +0 -19
  24. data/lib/mongomatic/validatable/validations/validates_length_of.rb +0 -32
  25. data/lib/mongomatic/validatable/validations/validates_numericality_of.rb +0 -28
  26. data/lib/mongomatic/validatable/validations/validates_presence_of.rb +0 -18
  27. data/lib/mongomatic/validatable/validations/validates_true_for.rb +0 -15
  28. data/lib/mongomatic/validatable/validations/validation_base.rb +0 -93
data/README.rdoc CHANGED
@@ -2,12 +2,23 @@
2
2
 
3
3
  Mongomatic allows you to map your Ruby objects to Mongo documents. It is designed to be fast and simple.
4
4
 
5
+ == What's different about Mongomatic?
6
+
7
+ * Follows Mongo idioms wherever possible.
8
+ * Only strives to do "just enough" and never too much.
9
+ * When possible, we defer to Mongo. For example, there's no Mongomatic query API, instead you use the same query hash syntax you would with the Ruby Mongo driver.
10
+ * No complex relationship management: if you want to model relationships then add your own finder methods.
11
+ * Minimal dependencies.
12
+
5
13
  == Basic Usage
6
14
 
7
15
  require 'mongomatic'
8
16
 
9
17
  class User < Mongomatic::Base
10
- validates_presence_of :name, :email
18
+ def validate
19
+ self.errors << ["Name", "can't be empty"] if self["name"].blank?
20
+ self.errors << ["Email", "can't be empty"] if self["email"].blank?
21
+ end
11
22
  end
12
23
 
13
24
  # set the db for all models:
@@ -24,42 +35,33 @@ Mongomatic allows you to map your Ruby objects to Mongo documents. It is designe
24
35
  => true
25
36
  u.insert
26
37
  => BSON::ObjectID('4c32834f0218236321000001')
27
- u
28
- => #<User:0x00000100d0cbf8 @doc={"name"=>"Ben", "email"=>"me@somewhere.com", "_id"=>BSON::ObjectID('4c32834f0218236321000001')}, @removed=false, @validation_context=nil, @errors={}, @_initialized_validate_callbacks=true>
38
+
29
39
  u["name"] = "Ben Myles"
30
40
  => "Ben Myles"
31
41
  u.update
32
- => 142
42
+ => 137
43
+
44
+ found = User.find_one({"name" => "Ben Myles"})
45
+ => #<User:0x00000101939a48 @doc={"_id"=>BSON::ObjectID('4c32834f0218236321000001'), "name"=>"Ben Myles", "email"=>"me@somewhere.com"}, @removed=false, @is_new=false, @errors=[]>
46
+ User.find_one(BSON::ObjectID('4c32834f0218236321000001')) == found
47
+ => true
33
48
 
34
49
  cursor = User.find({"name" => "Ben Myles"})
35
- => #<Mongomatic::Cursor:0x00000100cf5110 @obj_class=User, @mongo_cursor=DBResponse(flags=, cursor_id=, start=)> cursor.count
36
- cursor.count
37
- => 1
50
+ => #<Mongomatic::Cursor:0x0000010195b4e0 @obj_class=User, @mongo_cursor=<Mongo::Cursor:0x80cadac0 namespace='mongomatic_test.User' @selector={"name"=>"Ben Myles"}>>
38
51
  found = cursor.next
39
- => #<User:0x00000100ccd408 @doc={"_id"=>BSON::ObjectID('4c32c3720218236526000001'), "name"=>"Ben Myles", "email"=>"me@somewhere.com"}, @removed=false>
52
+ => #<User:0x00000101939a48 @doc={"_id"=>BSON::ObjectID('4c32834f0218236321000001'), "name"=>"Ben Myles", "email"=>"me@somewhere.com"}, @removed=false, @is_new=false, @errors=[]>
40
53
  found.remove
41
- => 72
42
- found
43
- => #<User:0x00000101091f80 @doc={"_id"=>BSON::ObjectID('4c32c4480218236538000001'), "name"=>"Ben Myles", "email"=>"me@somewhere.com"}, @removed=true>
44
- cursor = User.find({"name" => "Ben Myles"})
45
- => #<Mongomatic::Cursor:0x00000100d9eb20 @obj_class=User, @mongo_cursor=DBResponse(flags=, cursor_id=, start=)>
46
- cursor.count
47
- => 0
48
- cursor.next
54
+ => 67
55
+ User.count
56
+ => 0
57
+ User.find({"name" => "Ben Myles"}).next
49
58
  => nil
50
-
51
- found = User.find_one({"name" => "Ben Myles"})
52
- => #<User:0x00000100ccd408 @doc={"_id"=>BSON::ObjectID('4c32c3720218236526000001'), "name"=>"Ben Myles", "email"=>"me@somewhere.com"}, @removed=false>
53
- found = User.find_one(BSON::ObjectID('4c32c3720218236526000001'))
54
- => #<User:0x00000100ccd408 @doc={"_id"=>BSON::ObjectID('4c32c3720218236526000001'), "name"=>"Ben Myles", "email"=>"me@somewhere.com"}, @removed=false>
55
-
59
+
56
60
  == Indexes
57
61
 
58
62
  Mongomatic doesn't do anything special to support indexes, but here's the suggested convention:
59
63
 
60
- class Person < Mongomatic::Base
61
- validates_presence_of :name, :email
62
-
64
+ class Person < Mongomatic::Base
63
65
  class << self
64
66
  def create_indexes
65
67
  collection.create_index("email", :unique => true)
@@ -69,7 +71,69 @@ Mongomatic doesn't do anything special to support indexes, but here's the sugges
69
71
 
70
72
  You can run Person.create_indexes whenever you add new indexes, it won't throw an error if they already exist.
71
73
 
72
- If you have defined a unique index and want Mongomatic to raise an exception on a duplicate insert you need to use insert_safe or update_safe. The error thrown will be Mongo::OperationFailure. See the test suite for examples.
74
+ If you have defined a unique index and want Mongomatic to raise an exception on a duplicate insert you need to use insert! or update!. The error thrown will be Mongo::OperationFailure. See the test suite for examples.
75
+
76
+ == Validations
77
+
78
+ You can add validations to your model by creating a validate method. If your validate method pushes anything into the self.errors object your model will fail to validate, otherwise if self.errors remains empty the validations will be taken to have passed.
79
+
80
+ class Person < Mongomatic::Base
81
+ def validate
82
+ self.errors << ["name", "blank"] if self["name"].blank?
83
+ self.errors << ["email", "blank"] if self["email"].blank?
84
+ self.errors << ["address.zip", "blank"] if (self["address"] || {})["zip"].blank?
85
+ end
86
+ end
87
+
88
+ p = Person.new
89
+ => #<Person:0x000001018c2d58 @doc={}, @removed=false, @is_new=true, @errors=[]>
90
+ p.valid?
91
+ => false
92
+ p.errors
93
+ => [["name", "blank"], ["email", "blank"], ["address.zip", "blank"]]
94
+ p.errors.full_messages
95
+ => ["name blank", "email blank", "address.zip blank"]
96
+ p["name"] = "Ben"
97
+ p["email"] = "Myles"
98
+ p["address"] = { "zip" => 94107 }
99
+ p.valid?
100
+ => true
101
+
102
+ == Relationships
103
+
104
+ Mongomatic doesn't have any kind of special support for relationship management but it's easy to add this to your models where you need it. Here's an example that models Twitter-like followers on a User model:
105
+
106
+ class User < Mongomatic::Base
107
+ class << self
108
+ def create_indexes
109
+ self.collection.create_index("following_ids")
110
+ end
111
+ end
112
+
113
+ def follow(user)
114
+ self.push("following_ids", user["_id"])
115
+ end
116
+
117
+ def unfollow(user)
118
+ self.pull("following_ids", user["_id"])
119
+ end
120
+
121
+ def following
122
+ return nil if new?
123
+ self.class.find( { "_id" => { "$in" => (self["following_ids"] || []) } } )
124
+ end
125
+
126
+ def followers
127
+ return nil if new?
128
+ self.class.find( { "following_ids" => self["_id"] } )
129
+ end
130
+
131
+ def friends
132
+ return nil if new?
133
+ self.class.find( { "following_ids" => self["_id"],
134
+ "_id" => { "$in" => (self["following_ids"] || []) } } )
135
+ end
136
+ end
73
137
 
74
138
  == Note on Patches/Pull Requests
75
139
 
data/lib/mongomatic.rb CHANGED
@@ -27,8 +27,7 @@ module Mongomatic
27
27
  end
28
28
  end
29
29
 
30
- require "#{File.dirname(__FILE__)}/mongomatic/validatable"
31
-
32
30
  require "#{File.dirname(__FILE__)}/mongomatic/cursor"
33
31
  require "#{File.dirname(__FILE__)}/mongomatic/modifiers"
32
+ require "#{File.dirname(__FILE__)}/mongomatic/errors"
34
33
  require "#{File.dirname(__FILE__)}/mongomatic/base"
@@ -1,7 +1,6 @@
1
1
  module Mongomatic
2
2
  class Base
3
3
  include Mongomatic::Modifiers
4
- include Mongomatic::Validatable
5
4
 
6
5
  class << self
7
6
  def db
@@ -48,12 +47,25 @@ module Mongomatic
48
47
  end
49
48
  end
50
49
 
51
- attr_accessor :removed, :is_new
50
+ attr_accessor :removed, :is_new, :errors
52
51
 
53
52
  def initialize(doc={}, is_new=true)
54
53
  @doc = doc.stringify_keys
55
54
  self.removed = false
56
55
  self.is_new = is_new
56
+ self.errors = Mongomatic::Errors.new
57
+ end
58
+
59
+ def validate
60
+ true
61
+ end
62
+
63
+ def valid?
64
+ self.errors = Mongomatic::Errors.new
65
+ self.send(:before_validate) if self.respond_to?(:before_validate)
66
+ validate
67
+ self.send(:after_validate) if self.respond_to?(:after_validate)
68
+ self.errors.empty?
57
69
  end
58
70
 
59
71
  def is_new?
@@ -0,0 +1,7 @@
1
+ module Mongomatic
2
+ class Errors < Array
3
+ def full_messages(sep=" ")
4
+ collect { |e| e.join(sep) }
5
+ end
6
+ end
7
+ end
data/test/helper.rb CHANGED
@@ -10,13 +10,16 @@ require 'mongomatic'
10
10
  Mongomatic.db = Mongo::Connection.new.db("mongomatic_test")
11
11
 
12
12
  class Person < Mongomatic::Base
13
- validates_presence_of :name
14
13
  attr_accessor :callback_tests
15
14
 
16
15
  def self.create_indexes
17
16
  collection.create_index("name", :unique => true)
18
17
  end
19
18
 
19
+ def validate
20
+ self.errors << ["Name", "can't be empty"] if self["name"].blank?
21
+ end
22
+
20
23
  def before_validate
21
24
  self.callback_tests ||= []
22
25
  self.callback_tests << :before_validate
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 31
9
- version: 0.1.31
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ben Myles
@@ -105,29 +105,8 @@ files:
105
105
  - lib/mongomatic.rb
106
106
  - lib/mongomatic/base.rb
107
107
  - lib/mongomatic/cursor.rb
108
+ - lib/mongomatic/errors.rb
108
109
  - lib/mongomatic/modifiers.rb
109
- - lib/mongomatic/validatable.rb
110
- - lib/mongomatic/validatable/child_validation.rb
111
- - lib/mongomatic/validatable/errors.rb
112
- - lib/mongomatic/validatable/included_validation.rb
113
- - lib/mongomatic/validatable/macros.rb
114
- - lib/mongomatic/validatable/object_extension.rb
115
- - lib/mongomatic/validatable/requireable.rb
116
- - lib/mongomatic/validatable/understandable.rb
117
- - lib/mongomatic/validatable/validatable_class_methods.rb
118
- - lib/mongomatic/validatable/validatable_instance_methods.rb
119
- - lib/mongomatic/validatable/validations/validates_acceptance_of.rb
120
- - lib/mongomatic/validatable/validations/validates_associated.rb
121
- - lib/mongomatic/validatable/validations/validates_confirmation_of.rb
122
- - lib/mongomatic/validatable/validations/validates_each.rb
123
- - lib/mongomatic/validatable/validations/validates_exclusion_of.rb
124
- - lib/mongomatic/validatable/validations/validates_format_of.rb
125
- - lib/mongomatic/validatable/validations/validates_inclusion_of.rb
126
- - lib/mongomatic/validatable/validations/validates_length_of.rb
127
- - lib/mongomatic/validatable/validations/validates_numericality_of.rb
128
- - lib/mongomatic/validatable/validations/validates_presence_of.rb
129
- - lib/mongomatic/validatable/validations/validates_true_for.rb
130
- - lib/mongomatic/validatable/validations/validation_base.rb
131
110
  - LICENSE
132
111
  - README.rdoc
133
112
  - test/helper.rb
@@ -1,31 +0,0 @@
1
- # gem "activesupport", "2.3.5"
2
-
3
- require "forwardable"
4
-
5
- require "#{File.dirname(__FILE__)}/validatable/object_extension"
6
- require "#{File.dirname(__FILE__)}/validatable/errors"
7
- require "#{File.dirname(__FILE__)}/validatable/validatable_class_methods"
8
- require "#{File.dirname(__FILE__)}/validatable/macros"
9
- require "#{File.dirname(__FILE__)}/validatable/validatable_instance_methods"
10
- require "#{File.dirname(__FILE__)}/validatable/included_validation"
11
- require "#{File.dirname(__FILE__)}/validatable/child_validation"
12
- require "#{File.dirname(__FILE__)}/validatable/understandable"
13
- require "#{File.dirname(__FILE__)}/validatable/requireable"
14
- require "#{File.dirname(__FILE__)}/validatable/validations/validation_base"
15
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_format_of"
16
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_presence_of"
17
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_acceptance_of"
18
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_confirmation_of"
19
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_length_of"
20
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_true_for"
21
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_numericality_of"
22
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_exclusion_of"
23
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_inclusion_of"
24
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_each"
25
- require "#{File.dirname(__FILE__)}/validatable/validations/validates_associated"
26
-
27
- module Mongomatic
28
- module Validatable
29
- Version = "1.8.4"
30
- end
31
- end
@@ -1,17 +0,0 @@
1
- module Mongomatic
2
- module Validatable
3
- class ChildValidation #:nodoc:
4
- attr_accessor :attribute, :map, :should_validate_proc
5
-
6
- def initialize(attribute, map, should_validate_proc)
7
- @attribute = attribute
8
- @map = map
9
- @should_validate_proc = should_validate_proc
10
- end
11
-
12
- def should_validate?(instance)
13
- instance.instance_eval &should_validate_proc
14
- end
15
- end
16
- end
17
- end
@@ -1,108 +0,0 @@
1
- module Mongomatic
2
- module Validatable
3
- class Errors
4
- extend Forwardable
5
- include Enumerable
6
-
7
- def_delegators :errors, :clear, :each, :each_pair, :empty?, :length, :size
8
-
9
- # Returns true if the specified +attribute+ has errors associated with it.
10
- #
11
- # class Company < ActiveRecord::Base
12
- # validates_presence_of :name, :address, :email
13
- # validates_length_of :name, :in => 5..30
14
- # end
15
- #
16
- # company = Company.create(:address => '123 First St.')
17
- # company.errors.invalid?(:name) # => true
18
- # company.errors.invalid?(:address) # => false
19
- def invalid?(attribute)
20
- !@errors[attribute.to_sym].nil?
21
- end
22
-
23
- # Adds an error to the base object instead of any particular attribute. This is used
24
- # to report errors that don't tie to any specific attribute, but rather to the object
25
- # as a whole. These error messages don't get prepended with any field name when iterating
26
- # with +each_full+, so they should be complete sentences.
27
- def add_to_base(msg)
28
- add(:base, msg)
29
- end
30
-
31
- # Returns errors assigned to the base object through +add_to_base+ according to the normal rules of <tt>on(attribute)</tt>.
32
- def on_base
33
- on(:base)
34
- end
35
-
36
- # call-seq: on(attribute)
37
- #
38
- # * Returns nil, if no errors are associated with the specified +attribute+.
39
- # * Returns the error message, if one error is associated with the specified +attribute+.
40
- # * Returns an array of error messages, if more than one error is associated with the specified +attribute+.
41
- def on(attribute)
42
- return nil if errors[attribute.to_sym].nil?
43
- errors[attribute.to_sym].size == 1 ? errors[attribute.to_sym].first : errors[attribute.to_sym]
44
- end
45
-
46
- # Rails 3 API for errors, always return array.
47
- def [](attribute)
48
- errors[attribute.to_sym] || []
49
- end
50
-
51
- def add(attribute, message) #:nodoc:
52
- errors[attribute.to_sym] = [] if errors[attribute.to_sym].nil?
53
- errors[attribute.to_sym] << message
54
- end
55
-
56
- def merge!(errors) #:nodoc:
57
- errors.each_pair{|k, v| add(k,v)}
58
- self
59
- end
60
-
61
- # call-seq: replace(attribute)
62
- #
63
- # * Replaces the errors value for the given +attribute+
64
- def replace(attribute, value)
65
- errors[attribute.to_sym] = value
66
- end
67
-
68
- # call-seq: raw(attribute)
69
- #
70
- # * Returns an array of error messages associated with the specified +attribute+.
71
- def raw(attribute)
72
- errors[attribute.to_sym]
73
- end
74
-
75
- def errors #:nodoc:
76
- @errors ||= {}
77
- end
78
-
79
- def count #:nodoc:
80
- errors.values.flatten.size
81
- end
82
-
83
- # call-seq: full_messages -> an_array_of_messages
84
- #
85
- # Returns an array containing the full list of error messages.
86
- def full_messages
87
- full_messages = []
88
-
89
- errors.each_key do |attribute|
90
- errors[attribute].each do |msg|
91
- next if msg.nil?
92
-
93
- if attribute.to_s == "base"
94
- full_messages << msg
95
- else
96
- full_messages << humanize(attribute.to_s) + " " + msg
97
- end
98
- end
99
- end
100
- full_messages
101
- end
102
-
103
- def humanize(lower_case_and_underscored_word) #:nodoc:
104
- lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
105
- end
106
- end
107
- end
108
- end
@@ -1,11 +0,0 @@
1
- module Mongomatic
2
- module Validatable
3
- class IncludedValidation #:nodoc:
4
- attr_accessor :attribute
5
-
6
- def initialize(attribute)
7
- @attribute = attribute
8
- end
9
- end
10
- end
11
- end
@@ -1,316 +0,0 @@
1
- module Mongomatic
2
- module Validatable
3
- module Macros
4
- # call-seq: validates_each(*args)
5
- #
6
- # Validates that the logic evaluates to true
7
- #
8
- # class Address
9
- # include Validatable
10
- # validates_each :zip_code, :logic => lambda { errors.add(:zip_code, "is not valid") if ZipCodeService.allows(zip_code) }
11
- # end
12
- #
13
- # The logic option is required.
14
- #
15
- # Configuration options:
16
- #
17
- # * after_validate - A block that executes following the run of a validation
18
- # * group - The group that this validation belongs to. A validation can belong to multiple groups
19
- # * if - A block that when executed must return true of the validation will not occur
20
- # * level - The level at which the validation should occur
21
- # * logic - A block that executes to perform the validation
22
- # * message - The message to add to the errors collection when the validation fails
23
- # * times - The number of times the validation applies
24
- def validates_each(*args)
25
- add_validations(args, ValidatesEach)
26
- end
27
-
28
- # call-seq: validates_format_of(*args)
29
- #
30
- # Validates whether the value of the specified attribute is of the
31
- # correct form by matching it against the regular expression provided.
32
- #
33
- # class Person
34
- # include Validatable
35
- # validates_format_of :first_name, :with => /[ A-Za-z]/
36
- # end
37
- #
38
- # A regular expression must be provided or else an exception will be raised.
39
- #
40
- # Configuration options:
41
- #
42
- # * after_validate - A block that executes following the run of a validation
43
- # * message - The message to add to the errors collection when the validation fails
44
- # * times - The number of times the validation applies
45
- # * level - The level at which the validation should occur
46
- # * if - A block that when executed must return true of the validation will not occur
47
- # * with - The regular expression used to validate the format
48
- # * group - The group that this validation belongs to. A validation can belong to multiple groups
49
- def validates_format_of(*args)
50
- add_validations(args, ValidatesFormatOf)
51
- end
52
-
53
- # call-seq: validates_length_of(*args)
54
- #
55
- # Validates that the specified attribute matches the length restrictions supplied.
56
- #
57
- # class Person
58
- # include Validatable
59
- # validates_length_of :first_name, :maximum=>30
60
- # validates_length_of :last_name, :minimum=>30
61
- # end
62
- #
63
- # Configuration options:
64
- #
65
- # * after_validate - A block that executes following the run of a validation
66
- # * message - The message to add to the errors collection when the validation fails
67
- # * times - The number of times the validation applies
68
- # * level - The level at which the validation should occur
69
- # * if - A block that when executed must return true of the validation will not occur
70
- # * minimum - The minimum size of the attribute
71
- # * maximum - The maximum size of the attribute
72
- # * is - The size the attribute must be
73
- # * within - A range that the size of the attribute must fall within
74
- # * group - The group that this validation belongs to. A validation can belong to multiple groups
75
- def validates_length_of(*args)
76
- add_validations(args, ValidatesLengthOf)
77
- end
78
-
79
- # call-seq: validates_numericality_of(*args)
80
- #
81
- # Validates that the specified attribute is numeric.
82
- #
83
- # class Person
84
- # include Validatable
85
- # validates_numericality_of :age
86
- # end
87
- #
88
- # Configuration options:
89
- #
90
- # * after_validate - A block that executes following the run of a validation
91
- # * message - The message to add to the errors collection when the validation fails
92
- # * times - The number of times the validation applies
93
- # * level - The level at which the validation should occur
94
- # * if - A block that when executed must return true of the validation will not occur
95
- # * group - The group that this validation belongs to. A validation can belong to multiple groups
96
- # * only_integer - Whether the attribute must be an integer (default is false)
97
- def validates_numericality_of(*args)
98
- add_validations(args, ValidatesNumericalityOf)
99
- end
100
-
101
- # call-seq: validates_acceptance_of(*args)
102
- #
103
- # Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example:
104
- #
105
- # class Person
106
- # include Validatable
107
- # validates_acceptance_of :terms_of_service
108
- # validates_acceptance_of :eula, :message => "must be abided"
109
- # end
110
- #
111
- # Configuration options:
112
- #
113
- # * after_validate - A block that executes following the run of a validation
114
- # * message - The message to add to the errors collection when the validation fails
115
- # * times - The number of times the validation applies
116
- # * level - The level at which the validation should occur
117
- # * if - A block that when executed must return true of the validation will not occur
118
- # * group - The group that this validation belongs to. A validation can belong to multiple groups
119
- def validates_acceptance_of(*args)
120
- add_validations(args, ValidatesAcceptanceOf)
121
- end
122
-
123
- # call-seq: validates_confirmation_of(*args)
124
- #
125
- # Encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example:
126
- #
127
- # Class:
128
- # class PersonPresenter
129
- # include Validatable
130
- # validates_confirmation_of :user_name, :password
131
- # validates_confirmation_of :email_address, :message => "should match confirmation"
132
- # end
133
- #
134
- # View:
135
- # <%= password_field "person", "password" %>
136
- # <%= password_field "person", "password_confirmation" %>
137
- #
138
- # Configuration options:
139
- #
140
- # * after_validate - A block that executes following the run of a validation
141
- # * case_sensitive - Whether or not to apply case-sensitivity on the comparison. Defaults to true.
142
- # * message - The message to add to the errors collection when the validation fails
143
- # * times - The number of times the validation applies
144
- # * level - The level at which the validation should occur
145
- # * if - A block that when executed must return true of the validation will not occur
146
- # * group - The group that this validation belongs to. A validation can belong to multiple groups
147
- def validates_confirmation_of(*args)
148
- add_validations(args, ValidatesConfirmationOf)
149
- end
150
-
151
- # call-seq: validates_presence_of(*args)
152
- #
153
- # Validates that the specified attributes are not nil or an empty string
154
- #
155
- # class Person
156
- # include Validatable
157
- # validates_presence_of :first_name
158
- # end
159
- #
160
- # The first_name attribute must be in the object and it cannot be nil or empty.
161
- #
162
- # Configuration options:
163
- #
164
- # * after_validate - A block that executes following the run of a validation
165
- # * message - The message to add to the errors collection when the validation fails
166
- # * times - The number of times the validation applies
167
- # * level - The level at which the validation should occur
168
- # * if - A block that when executed must return true of the validation will not occur
169
- # * group - The group that this validation belongs to. A validation can belong to multiple groups
170
- def validates_presence_of(*args)
171
- add_validations(args, ValidatesPresenceOf)
172
- end
173
-
174
- # call-seq: validates_true_for(*args)
175
- #
176
- # Validates that the logic evaluates to true
177
- #
178
- # class Person
179
- # include Validatable
180
- # validates_true_for :first_name, :logic => lambda { first_name == 'Jamie' }
181
- # end
182
- #
183
- # The logic option is required.
184
- #
185
- # Configuration options:
186
- #
187
- # * after_validate - A block that executes following the run of a validation
188
- # * message - The message to add to the errors collection when the validation fails
189
- # * times - The number of times the validation applies
190
- # * level - The level at which the validation should occur
191
- # * if - A block that when executed must return true of the validation will not occur
192
- # * group - The group that this validation belongs to. A validation can belong to multiple groups
193
- # * logic - A block that executes to perform the validation
194
- def validates_true_for(*args)
195
- add_validations(args, ValidatesTrueFor)
196
- end
197
-
198
- def validates_exclusion_of(*args)
199
- add_validations(args, ValidatesExclusionOf)
200
- end
201
-
202
- def validates_inclusion_of(*args)
203
- add_validations(args, ValidatesInclusionOf)
204
- end
205
-
206
- # call-seq: validates_associated(*args)
207
- #
208
- # Checks the validity of an associated object or objects and adds a single
209
- # error if validation fails.
210
- #
211
- # class Person
212
- # include Validatable
213
- # attr_accessor :addresses
214
- # validates_associated :addresses
215
- # end
216
- #
217
- # Configuration options:
218
- #
219
- # * after_validate - A block that executes following the run of a validation
220
- # * message - The message to add to the errors collection when the validation fails
221
- # * times - The number of times the validation applies
222
- # * level - The level at which the validation should occur
223
- # * if - A block that when executed must return true of the validation will not occur
224
- # * group - The group that this validation belongs to. A validation can belong to multiple groups
225
- def validates_associated(*args)
226
- add_validations(args, ValidatesAssociated)
227
- end
228
-
229
- # call-seq: include_validations_from(attribute)
230
- #
231
- # Includes all the validations that are defined on the attribute.
232
- # class Person
233
- # include Validatable
234
- # validates_presence_of :name
235
- # end
236
- #
237
- # class PersonPresenter
238
- # include Validatable
239
- # include_validataions_from :person
240
- # attr_accessor :person
241
- # def name
242
- # person.name
243
- # end
244
- #
245
- # def initialize(person)
246
- # @person = person
247
- # end
248
- # end
249
- #
250
- # presenter = PersonPresenter.new(Person.new)
251
- # presenter.valid? #=> false
252
- # presenter.errors.on(:name) #=> "can't be blank"
253
- #
254
- # The name attribute whose validations should be added.
255
- def include_validations_from(attribute_to_validate, options = {})
256
- validations_to_include << IncludedValidation.new(attribute_to_validate)
257
- end
258
-
259
- # call-seq: include_errors_from(attribute_to_validate, options = {})
260
- #
261
- # Validates the specified attributes.
262
- # class Person
263
- # include Validatable
264
- # validates_presence_of :name
265
- # attr_accessor :name
266
- # end
267
- #
268
- # class PersonPresenter
269
- # include Validatable
270
- # include_errors_from :person, :map => { :name => :namen }, :if => lambda { not person.nil? }
271
- # attr_accessor :person
272
- #
273
- # def initialize(person)
274
- # @person = person
275
- # end
276
- # end
277
- #
278
- # presenter = PersonPresenter.new(Person.new)
279
- # presenter.valid? #=> false
280
- # presenter.errors.on(:namen) #=> "can't be blank"
281
- #
282
- # The person attribute will be validated.
283
- # If person is invalid the errors will be added to the PersonPresenter errors collection.
284
- #
285
- # Configuration options:
286
- #
287
- # * map - A hash that maps attributes of the child to attributes of the parent.
288
- # * if - A block that when executed must return true of the validation will not occur.
289
- def include_errors_from(attribute_to_validate, options = {})
290
- children_to_validate << ChildValidation.new(attribute_to_validate, options[:map] || {}, options[:if] || lambda { true })
291
- end
292
-
293
- def include_validations_for(attribute_to_validate, options = {}) #:nodoc:
294
- puts "include_validations_for is deprecated; use include_errors_from instead"
295
- children_to_validate << ChildValidation.new(attribute_to_validate, options[:map] || {}, options[:if] || lambda { true })
296
- end
297
-
298
- # call-seq: before_validation(&block)
299
- #
300
- # Is called before valid? or valid_for_*?
301
- #
302
- # class Person
303
- # include Validatable
304
- # before_validation do
305
- # self.name = "default name"
306
- # end
307
- #
308
- # attr_accessor :name
309
- # end
310
- #
311
- def before_validation(&block)
312
- before_validations << block
313
- end
314
- end
315
- end
316
- end