ninja-model 0.5.6 → 0.5.7

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.
@@ -23,6 +23,20 @@ module NinjaModel
23
23
  # Most of the following code was taken from ActiveRecord. Credit to the
24
24
  # Rails team is due.
25
25
  #
26
+ def klass
27
+ case type
28
+ when :integer then Fixnum
29
+ when :float then Float
30
+ when :decimal then BigDecimal
31
+ when :datetime then Time
32
+ when :date then Date
33
+ when :timestamp then Time
34
+ when :time then Time
35
+ when :text, :string then String
36
+ when :binary then String
37
+ when :boolean then Object
38
+ end
39
+ end
26
40
 
27
41
  def convert(value)
28
42
  case type
@@ -46,6 +46,22 @@ module NinjaModel
46
46
  end
47
47
 
48
48
  module AttributeMethods
49
+ class AttributeAssignmentError < NinjaModelError
50
+ attr_reader :exception, :attribute
51
+ attr_reader :mymessage
52
+ def initialize(message, exception, attribute)
53
+ @exception = exception
54
+ @attribute = attribute
55
+ @message = message
56
+ @mymessage = message
57
+ end
58
+ end
59
+ class MultiparameterAssignmentErrors < NinjaModelError
60
+ attr_reader :errors
61
+ def initialize(errors)
62
+ @errors = errors
63
+ end
64
+ end
49
65
 
50
66
  def attributes_from_model_attributes
51
67
  self.class.model_attributes.inject({}) do |result, attr|
@@ -84,9 +100,17 @@ module NinjaModel
84
100
  return unless new_attributes.is_a?(Hash)
85
101
  attributes = new_attributes.stringify_keys
86
102
 
103
+ multi_parameter_attributes = []
104
+
87
105
  attributes.each do |k,v|
88
- respond_to?("#{k}=".to_sym) ? send("#{k}=".to_sym, v) : raise(NinjaModel::Base::UnknownAttributeError, "unknown attribute: #{k}")
106
+ if k.include?('(')
107
+ multi_parameter_attributes << [k, v]
108
+ else
109
+ respond_to?("#{k}=".to_sym) ? send("#{k}=".to_sym, v) : raise(NinjaModel::Base::UnknownAttributeError, "unknown attribute: #{k}")
110
+ end
89
111
  end
112
+
113
+ assign_multiparameter_attributes(multi_parameter_attributes)
90
114
  end
91
115
 
92
116
  def attribute_method?(name)
@@ -96,6 +120,75 @@ module NinjaModel
96
120
 
97
121
  private
98
122
 
123
+ def assign_multiparameter_attributes(pairs)
124
+ execute_callstack_for_multiparameter_attributes(
125
+ extract_callstack_for_multiparameter_attributes(pairs)
126
+ )
127
+ end
128
+
129
+ def instantiate_time_object(name, values)
130
+ Time.time_with_datetime_fallback(@@default_timezone, *values)
131
+ end
132
+
133
+ def execute_callstack_for_multiparameter_attributes(callstack)
134
+ errors = []
135
+ callstack.each do |name, values_with_empty_parameters|
136
+ begin
137
+ klass = self.class.model_attributes_hash[name.to_s].klass
138
+ # in order to allow a date to be set without a year, we must keep the empty values.
139
+ # Otherwise, we wouldn't be able to distinguish it from a date with an empty day.
140
+ values = values_with_empty_parameters.reject { |v| v.nil? }
141
+
142
+ if values.empty?
143
+ send(name + "=", nil)
144
+ else
145
+
146
+ value = if Date == klass
147
+ begin
148
+ values = values_with_empty_parameters.collect do |v| v.nil? ? 1 : v end
149
+ Date.new(*values)
150
+ rescue ArgumentError => ex # if Date.new raises an exception on an invalid date
151
+ instantiate_time_object(name, values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
152
+ end
153
+ else
154
+ klass.new(*values)
155
+ end
156
+
157
+ send(name + "=", value)
158
+ end
159
+ rescue => ex
160
+ errors << AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name)
161
+ end
162
+ end
163
+ unless errors.empty?
164
+ raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
165
+ end
166
+ end
167
+
168
+ def extract_callstack_for_multiparameter_attributes(pairs)
169
+ attributes = { }
170
+
171
+ for pair in pairs
172
+ multiparameter_name, value = pair
173
+ attribute_name = multiparameter_name.split("(").first
174
+ attributes[attribute_name] = [] unless attributes.include?(attribute_name)
175
+
176
+ parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
177
+ attributes[attribute_name] << [ find_parameter_position(multiparameter_name), parameter_value ]
178
+ end
179
+
180
+ attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } }
181
+ end
182
+
183
+ def type_cast_attribute_value(multiparameter_name, value)
184
+ multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
185
+ end
186
+
187
+ def find_parameter_position(multiparameter_name)
188
+ multiparameter_name.scan(/\(([0-9]*).*\)/).first.first
189
+ end
190
+
191
+
99
192
  def attribute(name)
100
193
  read_attribute(name)
101
194
  end
@@ -1,3 +1,3 @@
1
1
  module NinjaModel
2
- VERSION = "0.5.6"
2
+ VERSION = "0.5.7"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ninja-model
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
- - 6
10
- version: 0.5.6
9
+ - 7
10
+ version: 0.5.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Josh Williams
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-29 00:00:00 -05:00
18
+ date: 2011-09-21 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency