validatable_associations 0.1.1 → 0.2.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
data/init.rb CHANGED
@@ -1 +1,7 @@
1
+ require "validatable_associations/has_one"
2
+
3
+ require "validatable_associations/mass_assignment"
4
+ require "validatable_associations/association"
5
+ require "validatable_associations/confirmation"
6
+
1
7
  require "validatable_associations"
@@ -4,114 +4,46 @@
4
4
  # library. This add-on lets you specify associations to other validatable Classes
5
5
  # and allows you to set up a decent validatable structure.
6
6
  module ValidatableAssociations
7
+ include MassAssignment
8
+ include Association
9
+ include Confirmation
7
10
 
8
11
  # ValidatableAssociations::ClassMethods
9
12
  #
10
- # Includes Class methods for setting up the associations.
13
+ # Includes Class methods from associations.
11
14
  module ClassMethods
12
-
13
- # Reader/writer method for has_one associations. Sets 1-n +associations+
14
- # or defaults to return all previously specified associations if no
15
- # parameters were given.
16
- def has_one(*associations)
17
- @has_one = [] unless @has_one
18
- return @has_one if associations.empty?
19
- @has_one += associations.map { |association| association.to_s }
20
- end
21
-
15
+ include ValidatableAssociations::HasOne::ClassMethods
22
16
  end
23
17
 
24
18
  def self.included(base) #:nodoc:
25
19
  base.extend(ClassMethods)
26
20
  end
27
21
 
28
- # The initialize method handles mass-assignment of a given Hash of
29
- # +attributes+ to their instance variables.
30
- def initialize(attributes = {})
31
- return if !attributes || attributes.empty?
32
- attributes.each { |ivar, value| assign_to(ivar, value) }
33
- end
34
-
35
22
  # Catches calls to undefined methods. Checks if the +method+ called matches
36
23
  # a reader/writer method of an association and handles the read/write process.
37
24
  # Delegates to super otherwise.
38
25
  def method_missing(method, *args)
39
- association_name = association_name_from(method)
40
- super unless self.class.has_one.include? association_name
26
+ method = clean_method_name(method)
41
27
 
42
- association_to_set = find_or_create_association(association_name, args[0])
43
- self.instance_variable_set("@#{association_name}", association_to_set)
44
- association_to_set
28
+ if association? method
29
+ handle_association(method, args[0])
30
+ elsif confirmation? method
31
+ handle_confirmation(method, args[0])
32
+ else
33
+ super
34
+ end
45
35
  rescue NameError
46
36
  super
47
37
  end
48
38
 
49
- # Returns whether the validations of this model and all associated models
50
- # passed successfully.
51
- def valid?
52
- validate_associations
53
- super && associations_valid?
54
- end
55
-
56
39
  private
57
40
 
58
- # Assigns a given +value+ to a given +ivar+. Tries to use the writer method
59
- # for the given instance variable and defaults to setting it directly in case
60
- # no writer method was found.
61
- def assign_to(ivar, value)
62
- if assign_via_writer? ivar
63
- self.send("#{ivar}=", value)
64
- else
65
- self.instance_variable_set("@#{ivar}", value)
66
- end
67
- end
68
-
69
- # Checks whether a given +ivar+ should be assigned via an existing writer
70
- # method or directly.
71
- def assign_via_writer?(ivar)
72
- self.methods.include?("#{ivar}=") || self.class.has_one.include?(ivar)
73
- end
74
-
75
- # Takes an +association_name+ and returns an existing association matching
76
- # the given name. Instantiates a new association in case it hasn't been
77
- # initialized already or in case of given +arguments+.
78
- def find_or_create_association(association_name, arguments = nil)
79
- if arguments
80
- constant_from(association_name).new arguments
81
- else
82
- association = self.instance_variable_get("@#{association_name}")
83
- association = constant_from(association_name).new unless association
84
- association
85
- end
86
- end
87
-
88
- # Validates all models associated with this model and stores the results.
89
- def validate_associations
90
- @association_validity = self.class.has_one.map do |association|
91
- self.send(association).valid?
92
- end
93
- end
94
-
95
- # Returns whether the validations of all models associated with this model
96
- # passed successfully.
97
- def associations_valid?
98
- !@association_validity.include?(false)
99
- end
100
-
101
41
  # Expects the name of a reader/writer +method+ and turns it into a valid
102
42
  # name for an association.
103
- def association_name_from(method)
104
- association_name = method.to_s
105
- association_name.slice!(-1) if association_name[-1, 1] == "="
106
- association_name
107
- end
108
-
109
- # Converts a given +symbol+ from snake_case into an existing Constant.
110
- # Note that the constanize method might raise a NameError in case the given
111
- # symbol could not be mapped to a Constant.
112
- def constant_from(symbol)
113
- symbol.to_s.camelize.constantize
43
+ def clean_method_name(method)
44
+ name = method.to_s
45
+ name.slice! -1 if name[-1, 1] == "="
46
+ name
114
47
  end
115
48
 
116
49
  end
117
-
@@ -0,0 +1,58 @@
1
+ module ValidatableAssociations
2
+ module Association
3
+
4
+ # Returns whether the validations of this model and all associated models
5
+ # passed successfully.
6
+ def valid?
7
+ validate_associations
8
+ super && associations_valid?
9
+ end
10
+
11
+ private
12
+
13
+ # Validates all models associated with this model and stores the results.
14
+ def validate_associations
15
+ @association_validity = self.class.has_one.map do |association|
16
+ self.send(association).valid?
17
+ end
18
+ end
19
+
20
+ # Returns whether the validations of all models associated with this model
21
+ # passed successfully.
22
+ def associations_valid?
23
+ !@association_validity.include? false
24
+ end
25
+
26
+ # Returns whether a given +method_name+ matches an association.
27
+ def association?(method_name)
28
+ self.class.has_one.include? method_name
29
+ end
30
+
31
+ def handle_association(association_name, argument)
32
+ association_to_set = find_or_create_association(association_name, argument)
33
+ self.instance_variable_set("@#{association_name}", association_to_set)
34
+ association_to_set
35
+ end
36
+
37
+ # Takes an +association_name+ and returns an existing association matching
38
+ # the given name. Instantiates a new association in case it hasn't been
39
+ # initialized already or in case of given +arguments+.
40
+ def find_or_create_association(association_name, arguments = nil)
41
+ if arguments
42
+ constant_from(association_name).new arguments
43
+ else
44
+ association = self.instance_variable_get("@#{association_name}")
45
+ association = constant_from(association_name).new unless association
46
+ association
47
+ end
48
+ end
49
+
50
+ # Converts a given +symbol+ from snake_case into an existing Constant.
51
+ # Note that the constanize method might raise a NameError in case the given
52
+ # symbol could not be mapped to a Constant.
53
+ def constant_from(symbol)
54
+ symbol.to_s.camelize.constantize
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,29 @@
1
+ module ValidatableAssociations
2
+ module Confirmation
3
+
4
+ private
5
+
6
+ def confirmation?(method_name)
7
+ if method_name[-13, 13] == "_confirmation"
8
+ method = method_name.dup
9
+ method.slice!(-13, 13)
10
+ else
11
+ method = method_name
12
+ end
13
+
14
+ self.public_methods.include? method
15
+ end
16
+
17
+ def handle_confirmation(confirmation, argument)
18
+ return self.instance_variable_get("@#{confirmation}") unless argument
19
+
20
+ if self.public_methods.include? "#{confirmation}="
21
+ self.send("#{confirmation}=", argument)
22
+ else
23
+ self.instance_variable_set("@#{confirmation}", argument)
24
+ end
25
+ argument
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,18 @@
1
+ module ValidatableAssociations
2
+ module HasOne
3
+
4
+ module ClassMethods
5
+
6
+ # Reader/writer method for has_one associations. Sets 1-n +associations+
7
+ # or defaults to return all previously specified associations if no
8
+ # parameters were given.
9
+ def has_one(*associations)
10
+ @has_one = [] unless @has_one
11
+ return @has_one if associations.empty?
12
+ @has_one += associations.map { |association| association.to_s }
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ module ValidatableAssociations
2
+ module MassAssignment
3
+
4
+ # The initialize method handles mass-assignment of a given Hash of
5
+ # +attributes+ to their instance variables.
6
+ def initialize(attributes = {})
7
+ return if !attributes || attributes.empty?
8
+ attributes.each { |ivar, value| assign_to(ivar, value) }
9
+ end
10
+
11
+ private
12
+
13
+ # Assigns a given +value+ to a given +ivar+. Tries to use the writer method
14
+ # for the given instance variable and defaults to setting it directly in case
15
+ # no writer method was found.
16
+ def assign_to(ivar, value)
17
+ if assign_via_writer? ivar
18
+ self.send("#{ivar}=", value)
19
+ else
20
+ self.instance_variable_set("@#{ivar}", value)
21
+ end
22
+ end
23
+
24
+ # Checks whether a given +ivar+ should be assigned via an existing writer
25
+ # method or directly.
26
+ def assign_via_writer?(ivar)
27
+ self.methods.include?("#{ivar}=") || association?(ivar)
28
+ end
29
+
30
+ end
31
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validatable_associations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Harrington
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-21 00:00:00 +02:00
12
+ date: 2009-10-25 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -46,6 +46,10 @@ files:
46
46
  - VERSION
47
47
  - init.rb
48
48
  - lib/validatable_associations.rb
49
+ - lib/validatable_associations/association.rb
50
+ - lib/validatable_associations/confirmation.rb
51
+ - lib/validatable_associations/has_one.rb
52
+ - lib/validatable_associations/mass_assignment.rb
49
53
  - spec/lib/validatable_associations_spec.rb
50
54
  - spec/spec_helper.rb
51
55
  has_rdoc: true