motion_model 0.3.8 → 0.4.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/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ 2012-02-19: Included Doug Puchalski's great refactoring of Model that provides an
2
+ adapter for ArrayModelAdapter. WARNING!!! This is a breaking change
3
+ since version 0.3.8. You will have to include:
4
+
5
+ MotionModel::ArrayModelAdapter
6
+
7
+ after including MotionModel::Model to get the same functionality.
8
+ Failure to include an adapter (note: spelling counts :) will result
9
+ in an exception so this will not quietly fail.
10
+
1
11
  2012-01-24: Added block-structured transactions.
2
12
 
3
13
  2012-01-14: Fixed problem where data returned from forms was of type NSString, which
data/README.md CHANGED
@@ -31,6 +31,36 @@ you like with it. See the LICENSE file in this project.
31
31
  * [Problems/Comments](#problemscomments)
32
32
  * [Submissions/Patches](#submissionspatches)
33
33
 
34
+ Most Recent Important Change
35
+ =================
36
+
37
+ Please see the CHANGELOG for update on changes.
38
+
39
+ Version 0.3.8 to 0.4.0 is a minor version bump, not a patch version. Upgrading
40
+ to 0.4.0 *will break existing code*. To update your code, simply insert the following line:
41
+
42
+ ```ruby
43
+ class ModelWithAdapter
44
+ include MotionModel::Model
45
+ include MotionModel::ArrayModelAdapter # <== Here!
46
+
47
+ columns :name
48
+ end
49
+ ```
50
+
51
+ This change lays the foundation for using other persistence adapters.
52
+ If you don't want to update all your models, install the gem:
53
+
54
+ ```
55
+ $ gem install motion_model -v 0.3.8
56
+ ```
57
+
58
+ or if you are using bundler:
59
+
60
+ ```
61
+ gem motion_model, "0.3.8"
62
+ ```
63
+
34
64
  Getting Going
35
65
  ================
36
66
 
@@ -200,7 +230,7 @@ You must return `true` from your validator if the value passes validation otherw
200
230
  An important note about `save` once you include `Validatable`, you have two flavors
201
231
  of save:
202
232
 
203
- Method | Meaning
233
+ Method | Meaning
204
234
  -----------------------|---------------------------
205
235
  `save(options)` |Just saves the data if it is valid (passes validations) or if you have specified `:validate => false`
206
236
  `save!` |Saves the data if it is valid, otherwise raises a `MotionModel::Validatable::RecordInvalid` exception
@@ -0,0 +1,145 @@
1
+ module MotionModel
2
+ module ArrayModelAdapter
3
+ def adapter
4
+ 'Array Model Adapter'
5
+ end
6
+
7
+ def self.included(base)
8
+ base.extend(PrivateClassMethods)
9
+ base.extend(PublicClassMethods)
10
+ base.instance_variable_set("@collection", []) # Actual data
11
+ end
12
+
13
+ module PublicClassMethods
14
+
15
+ def collection
16
+ @collection ||= []
17
+ end
18
+
19
+ def insert(object)
20
+ collection << object
21
+ end
22
+
23
+ def length
24
+ collection.length
25
+ end
26
+ alias_method :count, :length
27
+
28
+ # Deletes all rows in the model -- no hooks are called and
29
+ # deletes are not cascading so this does not affected related
30
+ # data.
31
+ def delete_all
32
+ # Do each delete so any on_delete and
33
+ # cascades are called, then empty the
34
+ # collection and compact the array.
35
+ bulk_update do
36
+ collection.each{|item| item.delete}
37
+ end
38
+ @collection = []
39
+ @_next_id = 1
40
+ end
41
+
42
+ # Finds row(s) within the data store. E.g.,
43
+ #
44
+ # @post = Post.find(1) # find a specific row by ID
45
+ #
46
+ # or...
47
+ #
48
+ # @posts = Post.find(:author).eq('bob').all
49
+ def find(*args, &block)
50
+ if block_given?
51
+ matches = collection.collect do |item|
52
+ item if yield(item)
53
+ end.compact
54
+ return ArrayFinderQuery.new(matches)
55
+ end
56
+
57
+ unless args[0].is_a?(Symbol) || args[0].is_a?(String)
58
+ target_id = args[0].to_i
59
+ return collection.select{|element| element.id == target_id}.first
60
+ end
61
+
62
+ ArrayFinderQuery.new(args[0].to_sym, @collection)
63
+ end
64
+ alias_method :where, :find
65
+
66
+ # Returns query result as an array
67
+ def all
68
+ collection
69
+ end
70
+
71
+ def order(field_name = nil, &block)
72
+ ArrayFinderQuery.new(@collection).order(field_name, &block)
73
+ end
74
+
75
+ end
76
+
77
+ module PrivateClassMethods
78
+
79
+ # Returns next available id
80
+ def next_id #nodoc
81
+ @_next_id
82
+ end
83
+
84
+ # Sets next available id
85
+ def next_id=(value) #nodoc
86
+ @_next_id = value
87
+ end
88
+
89
+ # Increments next available id
90
+ def increment_id #nodoc
91
+ @_next_id += 1
92
+ end
93
+
94
+ end
95
+
96
+ def before_initialize(options)
97
+ assign_id(options)
98
+ end
99
+
100
+ # Undelete does pretty much as its name implies. However,
101
+ # the natural sort order is not preserved. IMPORTANT: If
102
+ # you are trying to undo a cascading delete, this will not
103
+ # work. It only undeletes the object you still own.
104
+
105
+ def undelete
106
+ collection << self
107
+ self.class.issue_notification(self, :action => 'add')
108
+ end
109
+
110
+ # Count of objects in the current collection
111
+ def length
112
+ collection.length
113
+ end
114
+ alias_method :count, :length
115
+
116
+ private
117
+
118
+ def assign_id(options) #nodoc
119
+ unless options[:id]
120
+ options[:id] = self.class.next_id
121
+ else
122
+ self.class.next_id = [options[:id].to_i, self.class.next_id].max
123
+ end
124
+ self.class.increment_id
125
+ end
126
+
127
+ def collection #nodoc
128
+ self.class.instance_variable_get('@collection')
129
+ end
130
+
131
+ def do_insert
132
+ collection << self
133
+ end
134
+
135
+ def do_update
136
+ end
137
+
138
+ def do_delete
139
+ target_index = collection.index{|item| item.id == self.id}
140
+ collection.delete_at(target_index) unless target_index.nil?
141
+ self.class.issue_notification(self, :action => 'delete')
142
+ end
143
+
144
+ end
145
+ end
@@ -1,5 +1,5 @@
1
1
  module MotionModel
2
- class FinderQuery
2
+ class ArrayFinderQuery
3
3
  attr_accessor :field_name
4
4
 
5
5
  def initialize(*args)#nodoc
@@ -16,7 +16,7 @@ module MotionModel
16
16
  def should_return(column) #nodoc
17
17
  skippable = [:id]
18
18
  skippable += [:created_at, :updated_at] unless @expose_auto_date_fields
19
- !skippable.include?(column) && !relation_column?(column)
19
+ !skippable.include?(column) && !self.class.relation_column?(column)
20
20
  end
21
21
 
22
22
  def returnable_columns #nodoc
@@ -40,6 +40,7 @@
40
40
  module MotionModel
41
41
  class PersistFileError < Exception; end
42
42
  class RelationIsNilError < Exception; end
43
+ class AdapterNotFoundError < Exception; end
43
44
 
44
45
  module Model
45
46
  def self.included(base)
@@ -48,7 +49,6 @@ module MotionModel
48
49
  base.instance_variable_set("@_columns", []) # Columns in model
49
50
  base.instance_variable_set("@_column_hashes", {}) # Hashes to for quick column lookup
50
51
  base.instance_variable_set("@_relations", {}) # relations
51
- base.instance_variable_set("@collection", []) # Actual data
52
52
  base.instance_variable_set("@_next_id", 1) # Next assignable id
53
53
  base.instance_variable_set("@_issue_notifications", true) # Next assignable id
54
54
  end
@@ -155,6 +155,14 @@ module MotionModel
155
155
  column_named(column).default || nil
156
156
  end
157
157
 
158
+ def read(attrs)
159
+ new(attrs).instance_eval do
160
+ @new_record = false
161
+ @dirty = false
162
+ self
163
+ end
164
+ end
165
+
158
166
  # Creates an object and saves it. E.g.:
159
167
  #
160
168
  # @bob = Person.create(:name => 'Bob', :hobby => 'Bird Watching')
@@ -166,25 +174,6 @@ module MotionModel
166
174
  row
167
175
  end
168
176
 
169
- def length
170
- @collection.length
171
- end
172
- alias_method :count, :length
173
-
174
- # Deletes all rows in the model -- no hooks are called and
175
- # deletes are not cascading so this does not affected related
176
- # data.
177
- def delete_all
178
- # Do each delete so any on_delete and
179
- # cascades are called, then empty the
180
- # collection and compact the array.
181
- bulk_update do
182
- @collection.each{|item| item.delete}
183
- end
184
- @collection = []
185
- @_next_id = 1
186
- end
187
-
188
177
  # Destroys all rows in the model -- before_delete and after_delete
189
178
  # hooks are called and deletes are not cascading if declared with
190
179
  # :delete => destroy in the has_many macro.
@@ -198,56 +187,23 @@ module MotionModel
198
187
  # Note collection is not emptied, and next_id is not reset.
199
188
  end
200
189
 
201
- # Finds row(s) within the data store. E.g.,
202
- #
203
- # @post = Post.find(1) # find a specific row by ID
204
- #
205
- # or...
206
- #
207
- # @posts = Post.find(:author).eq('bob').all
208
- def find(*args, &block)
209
- if block_given?
210
- matches = @collection.collect do |item|
211
- item if yield(item)
212
- end.compact
213
- return FinderQuery.new(matches)
214
- end
215
-
216
- unless args[0].is_a?(Symbol) || args[0].is_a?(String)
217
- target_id = args[0].to_i
218
- return @collection.select{|element| element.id == target_id}.first
219
- end
220
-
221
- FinderQuery.new(args[0].to_sym, @collection)
222
- end
223
- alias_method :where, :find
224
-
225
190
  # Retrieves first row of query
226
191
  def first
227
- @collection.first
192
+ all.first
228
193
  end
229
194
 
230
195
  # Retrieves last row of query
231
196
  def last
232
- @collection.last
233
- end
234
-
235
- # Returns query result as an array
236
- def all
237
- @collection
238
- end
239
-
240
- def order(field_name = nil, &block)
241
- FinderQuery.new(@collection).order(field_name, &block)
197
+ all.last
242
198
  end
243
199
 
244
200
  def each(&block)
245
201
  raise ArgumentError.new("each requires a block") unless block_given?
246
- @collection.each{|item| yield item}
202
+ all.each{|item| yield item}
247
203
  end
248
204
 
249
205
  def empty?
250
- @collection.empty?
206
+ all.empty?
251
207
  end
252
208
  end
253
209
 
@@ -339,19 +295,12 @@ module MotionModel
339
295
  @_column_hashes[name.to_sym]
340
296
  end
341
297
 
342
- # Returns next available id
343
- def next_id #nodoc
344
- @_next_id
345
- end
346
-
347
- # Sets next available id
348
- def next_id=(value) #nodoc
349
- @_next_id = value
298
+ def relation_column?(column) #nodoc
299
+ [:belongs_to, :belongs_to_id, :has_many].include? column_named(column).type
350
300
  end
351
301
 
352
- # Increments next available id
353
- def increment_id #nodoc
354
- @_next_id += 1
302
+ def virtual_relation_column?(column) #nodoc
303
+ [:belongs_to, :has_many].include? column_named(column).type
355
304
  end
356
305
 
357
306
  def has_relation?(col) #nodoc
@@ -369,12 +318,13 @@ module MotionModel
369
318
  end
370
319
 
371
320
  def initialize(options = {})
372
- @data ||= {}
321
+ raise AdapterNotFoundError.new("You must specify a persistence adapter.") unless self.respond_to? :adapter
373
322
 
374
- assign_id options
323
+ @data ||= {}
324
+ before_initialize(options)
375
325
 
376
326
  columns.each do |col|
377
- unless relation_column?(col) # all data columns
327
+ unless self.class.relation_column?(col) # all data columns
378
328
  initialize_data_columns col, options
379
329
  else
380
330
  @data[col] = options[col] if column_named(col).type == :belongs_to_id
@@ -382,6 +332,11 @@ module MotionModel
382
332
  end
383
333
 
384
334
  @dirty = true
335
+ @new_record = true
336
+ end
337
+
338
+ def new_record?
339
+ @new_record
385
340
  end
386
341
 
387
342
  # Default to_i implementation returns value of id column, much as
@@ -405,13 +360,14 @@ module MotionModel
405
360
  # Existing object implies update in place
406
361
  action = 'add'
407
362
  set_auto_date_field 'created_at'
408
- if obj = collection.find{|o| o.id == @data[:id]}
409
- obj = self
363
+ if @new_record
364
+ do_insert
365
+ else
366
+ do_update
410
367
  set_auto_date_field 'updated_at'
411
368
  action = 'update'
412
- else
413
- collection << self
414
369
  end
370
+ @new_record = false
415
371
  @dirty = false
416
372
  self.class.issue_notification(self, :action => action)
417
373
  end
@@ -422,7 +378,6 @@ module MotionModel
422
378
  self.send("#{field_name}=", Time.now) if self.respond_to? field_name
423
379
  end
424
380
 
425
- # Deletes the current object. The object can still be used.
426
381
  def call_hook(hook_name, postfix)
427
382
  hook = "#{hook_name}_#{postfix}"
428
383
  self.send(hook, self) if respond_to? hook.to_sym
@@ -436,11 +391,7 @@ module MotionModel
436
391
  end
437
392
 
438
393
  def delete
439
- call_hooks('delete') do
440
- target_index = collection.index{|item| item.id == self.id}
441
- collection.delete_at(target_index) unless target_index.nil?
442
- self.class.issue_notification(self, :action => 'delete')
443
- end
394
+ call_hooks('delete') { do_delete }
444
395
  end
445
396
 
446
397
  # Destroys the current object. The difference between delete
@@ -464,22 +415,6 @@ module MotionModel
464
415
  delete
465
416
  end
466
417
 
467
- # Undelete does pretty much as its name implies. However,
468
- # the natural sort order is not preserved. IMPORTANT: If
469
- # you are trying to undo a cascading delete, this will not
470
- # work. It only undeletes the object you still own.
471
-
472
- def undelete
473
- collection << self
474
- self.class.issue_notification(self, :action => 'add')
475
- end
476
-
477
- # Count of objects in the current collection
478
- def length
479
- collection.length
480
- end
481
- alias_method :count, :length
482
-
483
418
  # True if the column exists, otherwise false
484
419
  def column?(column_name)
485
420
  self.class.column?(column_name.to_sym)
@@ -518,30 +453,12 @@ module MotionModel
518
453
  @dirty
519
454
  end
520
455
 
521
-
522
456
  private
523
457
 
524
- def assign_id(options) #nodoc
525
- unless options[:id]
526
- options[:id] = self.class.next_id
527
- else
528
- self.class.next_id = [options[:id].to_i, self.class.next_id].max
529
- end
530
- self.class.increment_id
531
- end
532
-
533
- def relation_column?(column) #nodoc
534
- [:belongs_to, :belongs_to_id, :has_many].include? column_named(column).type
535
- end
536
-
537
458
  def initialize_data_columns(column, options) #nodoc
538
459
  self.send("#{column}=".to_sym, options[column] || self.class.default(column))
539
460
  end
540
461
 
541
- def collection #nodoc
542
- self.class.instance_variable_get('@collection')
543
- end
544
-
545
462
  def column_named(name) #nodoc
546
463
  self.class.column_named(name.to_sym)
547
464
  end
@@ -568,14 +485,5 @@ module MotionModel
568
485
  end
569
486
  end
570
487
 
571
- # Any way you reach this means you've tried to access a method
572
- # not defined on this model.
573
- def method_missing(method, *args, &block) #nodoc
574
- if self.respond_to? method
575
- return method(args, &block)
576
- else
577
- raise NoMethodError.new("nil column #{self.class}##{method} accessed from #{caller[1]}.")
578
- end
579
- end
580
488
  end
581
489
  end
@@ -1,4 +1,8 @@
1
-
1
+ # 0.3.8 is the last version without adapters.
2
+ # for backward compatibility, users should
3
+ # specify that version in their gem command
4
+ # or forward port their code to take advantage
5
+ # of adapters.
2
6
  module MotionModel
3
- VERSION = "0.3.8"
7
+ VERSION = "0.4.0"
4
8
  end
@@ -1,11 +1,13 @@
1
1
  class Assignee
2
2
  include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
3
4
  columns :assignee_name => :string
4
5
  belongs_to :task
5
6
  end
6
7
 
7
8
  class Task
8
9
  include MotionModel::Model
10
+ include MotionModel::ArrayModelAdapter
9
11
  columns :name => :string,
10
12
  :details => :string,
11
13
  :some_day => :date
@@ -14,6 +16,7 @@ end
14
16
 
15
17
  class CascadingTask
16
18
  include MotionModel::Model
19
+ include MotionModel::ArrayModelAdapter
17
20
  columns :name => :string,
18
21
  :details => :string,
19
22
  :some_day => :date
@@ -22,6 +25,7 @@ end
22
25
 
23
26
  class CascadedAssignee
24
27
  include MotionModel::Model
28
+ include MotionModel::ArrayModelAdapter
25
29
  columns :assignee_name => :string
26
30
  belongs_to :cascading_task
27
31
  has_many :employees
@@ -29,6 +33,7 @@ end
29
33
 
30
34
  class Employee
31
35
  include MotionModel::Model
36
+ include MotionModel::ArrayModelAdapter
32
37
  columns :name
33
38
  belongs_to :CascadedAssignee
34
39
  end
@@ -1,5 +1,6 @@
1
1
  class ModelWithOptions
2
2
  include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
3
4
 
4
5
  columns :date => {:type => :date, :formotion => {:picker_type => :date_time}}
5
6
  end
data/spec/date_spec.rb CHANGED
@@ -14,6 +14,7 @@ describe "time conversions" do
14
14
  it "Sets created_at when an item is created" do
15
15
  class Creatable
16
16
  include MotionModel::Model
17
+ include MotionModel::ArrayModelAdapter
17
18
  columns :name => :string,
18
19
  :created_at => :date
19
20
  end
@@ -25,6 +26,7 @@ describe "time conversions" do
25
26
  it "Sets updated_at when an item is created" do
26
27
  class Updateable
27
28
  include MotionModel::Model
29
+ include MotionModel::ArrayModelAdapter
28
30
  columns :name => :string,
29
31
  :created_at => :date,
30
32
  :updated_at => :date
data/spec/finder_spec.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  class Task
2
2
  include MotionModel::Model
3
- columns :name => :string,
3
+ include MotionModel::ArrayModelAdapter
4
+ columns :name => :string,
4
5
  :details => :string,
5
6
  :some_day => :date
6
7
  end
@@ -47,7 +48,7 @@ describe 'finders' do
47
48
  end
48
49
 
49
50
  it 'returns a FinderQuery object' do
50
- Task.where(:details).should.is_a(MotionModel::FinderQuery)
51
+ Task.where(:details).should.is_a(MotionModel::ArrayFinderQuery)
51
52
  end
52
53
 
53
54
  it 'using where instead of find' do
@@ -58,6 +59,7 @@ describe 'finders' do
58
59
  it "performs set inclusion(in) queries" do
59
60
  class InTest
60
61
  include MotionModel::Model
62
+ include MotionModel::ArrayModelAdapter
61
63
  columns :name
62
64
  end
63
65
 
@@ -92,7 +94,7 @@ describe 'finders' do
92
94
  end
93
95
 
94
96
  it 'returns a FinderQuery' do
95
- @items_less_than_5.should.is_a MotionModel::FinderQuery
97
+ @items_less_than_5.should.is_a MotionModel::ArrayFinderQuery
96
98
  end
97
99
 
98
100
  it 'handles block-style finders' do
@@ -1,5 +1,6 @@
1
1
  class ModelWithOptions
2
2
  include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
3
4
  include MotionModel::Formotion
4
5
 
5
6
  columns :name => :string,
@@ -13,6 +14,7 @@ end
13
14
 
14
15
  class RelatedModel
15
16
  include MotionModel::Model
17
+ include MotionModel::ArrayModelAdapter
16
18
 
17
19
  columns :name => :string
18
20
  belongs_to :model_with_options
@@ -1,5 +1,6 @@
1
1
  class TypeCast
2
2
  include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
3
4
  columns :a_boolean => :boolean,
4
5
  :an_int => {:type => :int, :default => 3},
5
6
  :an_integer => :integer,
@@ -3,7 +3,8 @@ class Task
3
3
  attr_reader :before_save_called, :after_save_called
4
4
 
5
5
  include MotionModel::Model
6
- columns :name => :string,
6
+ include MotionModel::ArrayModelAdapter
7
+ columns :name => :string,
7
8
  :details => :string,
8
9
  :some_day => :date
9
10
 
data/spec/model_spec.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  class Task
2
2
  include MotionModel::Model
3
- columns :name => :string,
3
+ include MotionModel::ArrayModelAdapter
4
+ columns :name => :string,
4
5
  :details => :string,
5
6
  :some_day => :date
6
7
 
@@ -11,11 +12,13 @@ end
11
12
 
12
13
  class ATask
13
14
  include MotionModel::Model
15
+ include MotionModel::ArrayModelAdapter
14
16
  columns :name, :details, :some_day
15
17
  end
16
18
 
17
19
  class TypeCast
18
20
  include MotionModel::Model
21
+ include MotionModel::ArrayModelAdapter
19
22
  columns :a_boolean => :boolean,
20
23
  :an_int => {:type => :int, :default => 3},
21
24
  :an_integer => :integer,
@@ -230,6 +233,15 @@ describe "Creating a model" do
230
233
  @new_task.save
231
234
  lambda{@new_task.name = 'now dirty'}.should.change{@new_task.dirty?}
232
235
  end
236
+
237
+ it 'marks an updated object as clean' do
238
+ @new_task.save
239
+ @new_task.should.not.be.dirty
240
+ @new_task.name = 'now updating task'
241
+ @new_task.should.be.dirty
242
+ @new_task.save
243
+ @new_task.should.not.be.dirty
244
+ end
233
245
  end
234
246
  end
235
247
 
@@ -1,5 +1,6 @@
1
1
  class NotifiableTask
2
2
  include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
3
4
  columns :name
4
5
  @@notification_called = false
5
6
  @@notification_details = :none
@@ -1,5 +1,6 @@
1
1
  class PersistTask
2
2
  include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
3
4
  columns :name, :desc
4
5
  end
5
6
 
@@ -33,6 +34,7 @@ describe 'persistence' do
33
34
  it 'column addition' do
34
35
  class Foo
35
36
  include MotionModel::Model
37
+ include MotionModel::ArrayModelAdapter
36
38
  columns :name => :string
37
39
  end
38
40
  @foo = Foo.create(:name=> 'Bob')
@@ -42,6 +44,7 @@ describe 'persistence' do
42
44
 
43
45
  class Foo
44
46
  include MotionModel::Model
47
+ include MotionModel::ArrayModelAdapter
45
48
  columns :name => :string,
46
49
  :address => :string
47
50
  end
@@ -58,6 +61,7 @@ describe 'persistence' do
58
61
  it "column removal" do
59
62
  class Foo
60
63
  include MotionModel::Model
64
+ include MotionModel::ArrayModelAdapter
61
65
  columns :name => :string, :desc => :string
62
66
  end
63
67
 
@@ -69,6 +73,7 @@ describe 'persistence' do
69
73
  Object.send(:remove_const, :Foo)
70
74
  class Foo
71
75
  include MotionModel::Model
76
+ include MotionModel::ArrayModelAdapter
72
77
  columns :name => :string,
73
78
  :address => :string
74
79
  end
@@ -86,6 +91,7 @@ describe 'persistence' do
86
91
  describe "remembering filename" do
87
92
  class Foo
88
93
  include MotionModel::Model
94
+ include MotionModel::ArrayModelAdapter
89
95
  columns :name => :string
90
96
  end
91
97
 
@@ -142,12 +148,14 @@ end
142
148
 
143
149
  class Parent
144
150
  include MotionModel::Model
151
+ include MotionModel::ArrayModelAdapter
145
152
  columns :name
146
153
  has_many :children
147
154
  end
148
155
 
149
156
  class Child
150
157
  include MotionModel::Model
158
+ include MotionModel::ArrayModelAdapter
151
159
  columns :name
152
160
  belongs_to :parent
153
161
  end
@@ -1,11 +1,13 @@
1
1
  class Assignee
2
2
  include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
3
4
  columns :assignee_name => :string
4
5
  belongs_to :task
5
6
  end
6
7
 
7
8
  class Task
8
9
  include MotionModel::Model
10
+ include MotionModel::ArrayModelAdapter
9
11
  columns :name => :string,
10
12
  :details => :string,
11
13
  :some_day => :date
@@ -15,6 +17,7 @@ end
15
17
 
16
18
  class User
17
19
  include MotionModel::Model
20
+ include MotionModel::ArrayModelAdapter
18
21
  columns :name => :string
19
22
 
20
23
  has_many :email_accounts
@@ -22,6 +25,7 @@ end
22
25
 
23
26
  class EmailAccount
24
27
  include MotionModel::Model
28
+ include MotionModel::ArrayModelAdapter
25
29
  columns :name => :string
26
30
  belongs_to :user
27
31
  end
@@ -1,5 +1,6 @@
1
1
  class TransactClass
2
2
  include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
3
4
  include MotionModel::Model::Transactions
4
5
  columns :name, :age
5
6
  has_many :transaction_things
@@ -7,6 +8,7 @@ end
7
8
 
8
9
  class TransactionThing
9
10
  include MotionModel::Model
11
+ include MotionModel::ArrayModelAdapter
10
12
  include MotionModel::Model::Transactions
11
13
  columns :thingie_description
12
14
  belongs_to :transact_class
@@ -1,5 +1,6 @@
1
1
  class ValidatableTask
2
2
  include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
3
4
  include MotionModel::Validatable
4
5
  columns :name => :string,
5
6
  :email => :string,
@@ -137,6 +138,7 @@ end
137
138
 
138
139
  class VTask
139
140
  include MotionModel::Model
141
+ include MotionModel::ArrayModelAdapter
140
142
  include MotionModel::Validatable
141
143
 
142
144
  columns :name => :string
@@ -167,4 +169,4 @@ describe "saving with validations" do
167
169
  lambda { task.save }.should.change { VTask.count }
168
170
  end
169
171
 
170
- end
172
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.8
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-17 00:00:00.000000000 Z
12
+ date: 2013-02-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bubble-wrap
@@ -41,10 +41,11 @@ files:
41
41
  - Rakefile
42
42
  - app/app_delegate.rb
43
43
  - lib/motion_model.rb
44
+ - lib/motion_model/adapters/array_model_adapter.rb
44
45
  - lib/motion_model/ext.rb
45
46
  - lib/motion_model/input_helpers.rb
47
+ - lib/motion_model/model/array_finder_query.rb
46
48
  - lib/motion_model/model/column.rb
47
- - lib/motion_model/model/finder_query.rb
48
49
  - lib/motion_model/model/formotion.rb
49
50
  - lib/motion_model/model/model.rb
50
51
  - lib/motion_model/model/model_casts.rb