ninja-model 0.5.6 → 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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