motion_model 0.3.8 → 0.4.0

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