motion_model 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,7 +6,7 @@ module MotionModel
6
6
  when TrueClass, FalseClass then arg
7
7
  when Integer then arg != 0
8
8
  when String then (arg =~ /^true/i) != nil
9
- else raise ArgumentError.new("type #{column_name} : #{type(column_name)} is not possible to cast.")
9
+ else raise ArgumentError.new("type #{column_name} : #{column_type(column_name)} is not possible to cast.")
10
10
  end
11
11
  end
12
12
 
@@ -23,14 +23,18 @@ module MotionModel
23
23
  when String
24
24
  return NSDate.dateWithNaturalLanguageString(arg.gsub('-','/'), locale:NSUserDefaults.standardUserDefaults.dictionaryRepresentation)
25
25
  when Time
26
- return NSDate.dateWithNaturalLanguageString(arg.strftime('%Y/%m/%d %H:%M'), locale:NSUserDefaults.standardUserDefaults.dictionaryRepresentation)
26
+ return NSDate.dateWithNaturalLanguageString(arg.strftime('%Y/%m/%d %H:%M:%S'), locale:NSUserDefaults.standardUserDefaults.dictionaryRepresentation)
27
27
  else
28
28
  return arg
29
29
  end
30
30
  end
31
31
 
32
32
  def cast_to_array(arg)
33
- arg.is_a?(Array) ? Array(arg) : arg.to_a
33
+ Array(arg)
34
+ end
35
+
36
+ def cast_to_hash(arg)
37
+ arg.is_a?(String) ? BW::JSON.parse(String(arg)) : arg
34
38
  end
35
39
 
36
40
  def cast_to_string(arg)
@@ -38,18 +42,19 @@ module MotionModel
38
42
  end
39
43
 
40
44
  def cast_to_type(column_name, arg) #nodoc
41
- return nil if arg.nil? && ![ :boolean, :bool ].include?(type(column_name))
45
+ return nil if arg.nil? && ![ :boolean, :bool ].include?(column_type(column_name))
42
46
 
43
- return case type(column_name)
44
- when :string then cast_to_string(arg)
47
+ return case column_type(column_name)
48
+ when :string, :belongs_to_type then cast_to_string(arg)
45
49
  when :boolean, :bool then cast_to_bool(arg)
46
50
  when :int, :integer, :belongs_to_id then cast_to_integer(arg)
47
51
  when :float, :double then cast_to_float(arg)
48
- when :date, :time then cast_to_date(arg)
52
+ when :date, :time, :datetime then cast_to_date(arg)
49
53
  when :text then cast_to_string(arg)
50
54
  when :array then cast_to_array(arg)
55
+ when :hash then cast_to_hash(arg)
51
56
  else
52
- raise ArgumentError.new("type #{column_name} : #{type(column_name)} is not possible to cast.")
57
+ raise ArgumentError.new("type #{column_name} : #{column_type(column_name)} is not possible to cast.")
53
58
  end
54
59
  end
55
60
  end
@@ -21,7 +21,7 @@ module MotionModel
21
21
  end
22
22
 
23
23
  def columns_without_relations
24
- columns.select{|col| ![:has_many, :belongs_to].include?(type(col))}
24
+ columns.select{|col| ![:has_many, :belongs_to].include?(column_type(col))}
25
25
  end
26
26
 
27
27
  def restore_attributes
@@ -3,10 +3,8 @@ module MotionModel
3
3
  class ValidationSpecificationError < RuntimeError; end
4
4
  class RecordInvalid < RuntimeError; end
5
5
 
6
-
7
6
  def self.included(base)
8
7
  base.extend(ClassMethods)
9
- base.instance_variable_set('@validations', [])
10
8
  end
11
9
 
12
10
  module ClassMethods
@@ -16,25 +14,39 @@ module MotionModel
16
14
  raise ex
17
15
  end
18
16
 
19
-
20
-
21
17
  if validation_type == {}
22
18
  ex = ValidationSpecificationError.new('validation type not present or not a hash')
23
19
  raise ex
24
20
  end
25
21
 
26
- @validations << {field => validation_type}
22
+ validations << {field => validation_type}
27
23
  end
28
24
  alias_method :validates, :validate
29
25
 
30
26
  def validations
31
- @validations
27
+ @validations ||= []
32
28
  end
33
29
  end
34
-
35
- # It doesn't save when validations fails
36
- def save(options={ :validate => true})
37
- (valid? || !options[:validate]) ? super : false
30
+
31
+ def do_save?(options = {})
32
+ _valid = true
33
+ if options[:validate] != false
34
+ call_hooks 'validation' do
35
+ _valid = valid?
36
+ end
37
+ end
38
+ _valid
39
+ end
40
+ private :do_save?
41
+
42
+ def do_insert(options = {})
43
+ return false unless do_save?(options)
44
+ super
45
+ end
46
+
47
+ def do_update(options = {})
48
+ return false unless do_save?(options)
49
+ super
38
50
  end
39
51
 
40
52
  # it fails loudly
@@ -49,10 +61,12 @@ module MotionModel
49
61
  #
50
62
  # * Second, it returns the result of performing the validations.
51
63
  def valid?
52
- @messages = []
53
- @valid = true
54
- self.class.validations.each do |validations|
55
- validate_each(validations)
64
+ call_hooks 'validation' do
65
+ @messages = []
66
+ @valid = true
67
+ self.class.validations.each do |validations|
68
+ validate_each(validations)
69
+ end
56
70
  end
57
71
  @valid
58
72
  end
@@ -129,7 +143,7 @@ module MotionModel
129
143
  elsif value.is_a?(String) || value.nil?
130
144
  result = value.nil? || ((value.length == 0) == setting)
131
145
  additional_message = setting ? "non-empty" : "non-empty"
132
- add_message(field, "incorrect value supplied for #{field.to_s.humanize} -- should be #{additional_message}.") if result
146
+ add_message(field, "incorrect value supplied for #{field.to_s} -- should be #{additional_message}.") if result
133
147
  return !result
134
148
  end
135
149
  return false
@@ -4,5 +4,5 @@
4
4
  # or forward port their code to take advantage
5
5
  # of adapters.
6
6
  module MotionModel
7
- VERSION = "0.4.1"
7
+ VERSION = "0.4.2"
8
8
  end
@@ -0,0 +1,30 @@
1
+ class ModelWithAdapter
2
+ include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
4
+
5
+ columns :name
6
+ end
7
+
8
+ describe 'adapters with adapter method defined' do
9
+ it "does not raise an exception" do
10
+ lambda{ModelWithAdapter.create(:name => 'bob')}.should.not.raise
11
+ end
12
+
13
+ it "provides humanized string representation of the current adapter" do
14
+ ModelWithAdapter.create(:name => 'bob').adapter.should == 'Array Model Adapter'
15
+ end
16
+ end
17
+
18
+ class ModelWithoutAdapter
19
+ include MotionModel::Model
20
+
21
+ columns :name
22
+ end
23
+
24
+ describe 'adapters without adapter method defined' do
25
+ it "raises an exception" do
26
+ lambda{
27
+ ModelWithoutAdapter.new
28
+ }.should.raise(MotionModel::AdapterNotFoundError)
29
+ end
30
+ end
@@ -0,0 +1,229 @@
1
+ class PersistTask
2
+ include MotionModel::Model
3
+ include MotionModel::ArrayModelAdapter
4
+ columns :name => :string,
5
+ :desc => :string,
6
+ :created_at => :date,
7
+ :updated_at => :date
8
+ end
9
+
10
+ describe 'persistence' do
11
+ before do
12
+ PersistTask.delete_all
13
+ %w(one two three).each do |task|
14
+ @tasks = PersistTask.create(:name => "name #{task}")
15
+ end
16
+ end
17
+
18
+ it "serializes data" do
19
+ lambda{PersistTask.serialize_to_file('test.dat')}.should.not.raise
20
+ end
21
+
22
+ it 'reads persisted model data' do
23
+ PersistTask.serialize_to_file('test.dat')
24
+
25
+ PersistTask.delete_all
26
+
27
+ PersistTask.count.should == 0
28
+
29
+ tasks = PersistTask.deserialize_from_file('test.dat')
30
+
31
+ PersistTask.count.should == 3
32
+ PersistTask.first.name.should == 'name one'
33
+ PersistTask.last.name.should == 'name three'
34
+ end
35
+
36
+ it "does not change created or updated date on load" do
37
+ created_at = PersistTask.first.created_at
38
+ updated_at = PersistTask.first.updated_at
39
+
40
+ PersistTask.serialize_to_file('test.dat')
41
+ tasks = PersistTask.deserialize_from_file('test.dat')
42
+ puts tasks.inspect
43
+ PersistTask.first.created_at.should == created_at
44
+ PersistTask.first.updated_at.should == updated_at
45
+ end
46
+
47
+ describe 'model change resiliency' do
48
+ it 'column addition' do
49
+ Object.send(:remove_const, :Foo) if defined?(Foo)
50
+ class Foo
51
+ include MotionModel::Model
52
+ include MotionModel::ArrayModelAdapter
53
+ columns :name => :string
54
+ end
55
+ @foo = Foo.create(:name=> 'Bob')
56
+ Foo.serialize_to_file('test.dat')
57
+
58
+ @foo.should.not.respond_to :address
59
+
60
+ Foo.delete_all
61
+ class Foo
62
+ columns :address => :string
63
+ end
64
+ Foo.deserialize_from_file('test.dat')
65
+
66
+ @foo = Foo.first
67
+
68
+ @foo.name.should == 'Bob'
69
+ @foo.address.should == nil
70
+ @foo.should.respond_to :address
71
+ Foo.length.should == 1
72
+ end
73
+
74
+ it "column removal" do
75
+ Object.send(:remove_const, :Foo) if defined?(Foo)
76
+ class Foo
77
+ include MotionModel::Model
78
+ include MotionModel::ArrayModelAdapter
79
+ columns :name => :string, :desc => :string
80
+ end
81
+
82
+ @foo = Foo.create(:name=> 'Bob', :desc => 'who cares anyway?')
83
+ Foo.serialize_to_file('test.dat')
84
+
85
+ @foo.should.respond_to :desc
86
+
87
+ Object.send(:remove_const, :Foo) if defined?(Foo)
88
+ class Foo
89
+ include MotionModel::Model
90
+ include MotionModel::ArrayModelAdapter
91
+ columns :name => :string,
92
+ :address => :string
93
+ end
94
+ Foo.deserialize_from_file('test.dat')
95
+ end
96
+ end
97
+
98
+ describe "array model migrations" do
99
+ class TestForColumnAddition
100
+ include MotionModel::Model
101
+ include MotionModel::ArrayModelAdapter
102
+ columns :name => :string, :desc => :string
103
+ end
104
+
105
+ it "column addition should call migrate first as a test" do
106
+ TestForColumnAddition.mock!(:migrate)
107
+ TestForColumnAddition.deserialize_from_file('dfca.dat')
108
+ 1.should == 1
109
+ end
110
+
111
+ it "this example should pass" do
112
+ 1.should == 1
113
+ end
114
+
115
+ it "accepts properly formatted version strings" do
116
+ lambda{TestForColumnAddition.schema_version("3.1")}.should.not.raise
117
+ end
118
+
119
+ it "rejects non-string versions" do
120
+ lambda{TestForColumnAddition.schema_version(3)}.should.raise(MotionModel::ArrayModelAdapter::VersionNumberError)
121
+ end
122
+
123
+ it "rejects improperly formated version strings" do
124
+ lambda{TestForColumnAddition.schema_version("3/1/1")}.should.raise(MotionModel::ArrayModelAdapter::VersionNumberError)
125
+ end
126
+
127
+ it "returns the version number if no arguments supplied" do
128
+ TestForColumnAddition.schema_version("3.1")
129
+ TestForColumnAddition.schema_version.should == "3.1"
130
+ end
131
+ end
132
+
133
+ describe "remembering filename" do
134
+ class Foo
135
+ include MotionModel::Model
136
+ include MotionModel::ArrayModelAdapter
137
+ columns :name => :string
138
+ end
139
+
140
+ before do
141
+ Foo.delete_all
142
+ @foo = Foo.create(:name => 'Bob')
143
+ end
144
+
145
+ it "deserializes from last file if no filename given (previous method serialize)" do
146
+ Foo.serialize_to_file('test.dat')
147
+ Foo.delete_all
148
+ Foo.count.should == 0
149
+ Foo.deserialize_from_file
150
+ Foo.count.should == 1
151
+ end
152
+
153
+ it "deserializes from last file if no filename given (previous method deserialize)" do
154
+ Foo.serialize_to_file('test.dat')
155
+ Foo.serialize_to_file('bogus.dat') # serialize sets default filename to something bogus
156
+ File.delete Foo.documents_file('bogus.dat') # and we get rid of that file
157
+ Foo.deserialize_from_file('test.dat') # so we'll be sure the default filename last was set by deserialize
158
+ Foo.delete_all
159
+ Foo.count.should == 0
160
+ Foo.deserialize_from_file
161
+ Foo.count.should == 1
162
+ end
163
+
164
+ it "serializes to last file if no filename given (previous method serialize)" do
165
+ Foo.serialize_to_file('test.dat')
166
+ Foo.create(:name => 'Ted')
167
+ Foo.serialize_to_file
168
+ Foo.delete_all
169
+ Foo.count.should == 0
170
+ Foo.deserialize_from_file('test.dat')
171
+ Foo.count.should == 2
172
+ end
173
+
174
+ it "serializes to last file if no filename given (previous method deserialize)" do
175
+ Foo.serialize_to_file('test.dat')
176
+ Foo.delete_all
177
+ Foo.serialize_to_file('bogus.dat') # serialize sets default filename to something bogus
178
+ File.delete Foo.documents_file('bogus.dat') # and we get rid of that file
179
+ Foo.deserialize_from_file('test.dat') # so we'll be sure the default filename was last set by deserialize
180
+ Foo.create(:name => 'Ted')
181
+ Foo.serialize_to_file
182
+ Foo.delete_all
183
+ Foo.count.should == 0
184
+ Foo.deserialize_from_file('test.dat')
185
+ Foo.count.should == 2
186
+ end
187
+
188
+ end
189
+ end
190
+
191
+ class Parent
192
+ include MotionModel::Model
193
+ include MotionModel::ArrayModelAdapter
194
+ columns :name
195
+ has_many :children
196
+ end
197
+
198
+ class Child
199
+ include MotionModel::Model
200
+ include MotionModel::ArrayModelAdapter
201
+ columns :name
202
+ belongs_to :parent
203
+ end
204
+
205
+ describe "serialization of relations" do
206
+ before do
207
+ parent = Parent.create(:name => 'BoB')
208
+ parent.children_relation.create :name => 'Fergie'
209
+ parent.children_relation.create :name => 'Will I Am'
210
+ end
211
+
212
+ it "is wired up right" do
213
+ Parent.first.name.should == 'BoB'
214
+ Parent.first.children.count.should == 2
215
+ end
216
+
217
+ it "serializes and deserializes properly" do
218
+ Parent.serialize_to_file('parents.dat')
219
+ Child.serialize_to_file('children.dat')
220
+ Parent.delete_all
221
+ Child.delete_all
222
+ Parent.deserialize_from_file('parents.dat')
223
+ Child.deserialize_from_file('children.dat')
224
+ Parent.first.name.should == 'BoB'
225
+ Parent.first.children.count.should == 2
226
+ Parent.first.children.first.name.should == 'Fergie'
227
+ end
228
+ end
229
+
@@ -58,8 +58,8 @@ describe "cascading deletes" do
58
58
 
59
59
  it "deletes assignees that belong to a destroyed task" do
60
60
  task = CascadingTask.create(:name => 'cascading')
61
- task.cascaded_assignees.create(:assignee_name => 'joe')
62
- task.cascaded_assignees.create(:assignee_name => 'bill')
61
+ task.cascaded_assignees_relation.create(:assignee_name => 'joe')
62
+ task.cascaded_assignees_relation.create(:assignee_name => 'bill')
63
63
 
64
64
  CascadingTask.count.should == 1
65
65
  CascadedAssignee.count.should == 2
@@ -74,7 +74,7 @@ describe "cascading deletes" do
74
74
  1.upto(3) do |item|
75
75
  task = CascadingTask.create :name => "Task #{item}"
76
76
  1.upto(3) do |assignee|
77
- task.cascaded_assignees.create :name => "assignee #{assignee} for task #{task}"
77
+ task.cascaded_assignees_relation.create :assignee_name => "assignee #{assignee} for task #{task}"
78
78
  end
79
79
  end
80
80
  CascadingTask.count.should == 3
@@ -88,8 +88,8 @@ describe "cascading deletes" do
88
88
 
89
89
  it "deletes only one level when a task is destroyed but dependent is delete" do
90
90
  task = CascadingTask.create :name => 'dependent => :delete'
91
- assignee = task.cascaded_assignees.create :assignee_name => 'deletable assignee'
92
- assignee.employees.create :name => 'person who sticks around'
91
+ assignee = task.cascaded_assignees_relation.create :assignee_name => 'deletable assignee'
92
+ assignee.employees_relation.create :name => 'person who sticks around'
93
93
 
94
94
  CascadingTask.count.should == 1
95
95
  CascadedAssignee.count.should == 1
data/spec/date_spec.rb CHANGED
@@ -11,7 +11,8 @@ describe "time conversions" do
11
11
  should == "03-18-2012 | 07:00 PM"
12
12
  end
13
13
 
14
- it "Sets created_at when an item is created" do
14
+ describe "auto_date_fields" do
15
+
15
16
  class Creatable
16
17
  include MotionModel::Model
17
18
  include MotionModel::ArrayModelAdapter
@@ -19,25 +20,37 @@ describe "time conversions" do
19
20
  :created_at => :date
20
21
  end
21
22
 
22
- c = Creatable.new(:name => 'test')
23
- lambda{c.save}.should.change{c.created_at}
24
- end
25
-
26
- it "Sets updated_at when an item is created" do
27
23
  class Updateable
28
24
  include MotionModel::Model
29
25
  include MotionModel::ArrayModelAdapter
30
26
  columns :name => :string,
31
- :created_at => :date,
32
27
  :updated_at => :date
33
28
  end
34
29
 
35
- c = Updateable.create(:name => 'test')
36
- c.name = 'test 1'
37
- lambda{c.save}.should.not.change{c.created_at}
38
- d = Updateable.create(:name => 'test')
39
- d.name = 'test 2'
40
- lambda{d.save}.should.change{d.updated_at}
30
+ it "Sets created_at when an item is created" do
31
+ c = Creatable.new(:name => 'test')
32
+ lambda{c.save}.should.change{c.created_at}
33
+ end
34
+
35
+ it "Sets updated_at when an item is created" do
36
+ c = Updateable.new(:name => 'test')
37
+ lambda{c.save}.should.change{c.updated_at}
38
+ end
39
+
40
+ it "Doesn't update created_at when an item is updated" do
41
+ c = Creatable.create(:name => 'test')
42
+ c.name = 'test 1'
43
+ lambda{c.save}.should.not.change{c.created_at}
44
+ end
45
+
46
+ it "Updates updated_at when an item is updated" do
47
+ c = Updateable.create(:name => 'test')
48
+ sleep 1
49
+ c.name = 'test 1'
50
+ lambda{ c.save }.should.change{c.updated_at}
51
+ end
52
+
41
53
  end
42
54
 
55
+
43
56
  end
data/spec/finder_spec.rb CHANGED
@@ -77,6 +77,7 @@ describe 'finders' do
77
77
  end
78
78
 
79
79
  it 'all returns all members of the collection as an array' do
80
+ Task.all.each { |t| puts t }
80
81
  Task.all.length.should.equal(10)
81
82
  end
82
83
 
@@ -1,3 +1,4 @@
1
+ Object.send(:remove_const, :ModelWithOptions) if defined?(ModelWithOptions)
1
2
  class ModelWithOptions
2
3
  include MotionModel::Model
3
4
  include MotionModel::ArrayModelAdapter
@@ -1,3 +1,4 @@
1
+ Object.send(:remove_const, :Task) if defined?(Task)
1
2
  class Task
2
3
  attr_reader :before_delete_called, :after_delete_called
3
4
  attr_reader :before_save_called, :after_save_called
@@ -8,19 +9,19 @@ class Task
8
9
  :details => :string,
9
10
  :some_day => :date
10
11
 
11
- def before_delete(object)
12
+ def before_delete(sender)
12
13
  @before_delete_called = true
13
14
  end
14
15
 
15
- def after_delete(object)
16
+ def after_delete(sender)
16
17
  @after_delete_called = true
17
18
  end
18
19
 
19
- def before_save(object)
20
+ def before_save(sender)
20
21
  @before_save_called = true
21
22
  end
22
23
 
23
- def after_save(object)
24
+ def after_save(sender)
24
25
  @after_save_called = true
25
26
  end
26
27
 
data/spec/model_spec.rb CHANGED
@@ -45,12 +45,6 @@ describe "Creating a model" do
45
45
  atask.should.respond_to(:details)
46
46
  end
47
47
 
48
- it 'simply bypasses spurious attributes erroneously set' do
49
- a_task = Task.new(:name => 'details', :zoo => 'very bad')
50
- a_task.should.not.respond_to(:zoo)
51
- a_task.name.should.equal('details')
52
- end
53
-
54
48
  it "adds a default value if none supplied" do
55
49
  a_type_test = TypeCast.new
56
50
  a_type_test.an_int.should.equal(3)
@@ -89,7 +83,7 @@ describe "Creating a model" do
89
83
  end
90
84
 
91
85
  it "the type of a column can be retrieved" do
92
- Task.new.type(:some_day).should.equal(:date)
86
+ Task.new.column_type(:some_day).should.equal(:date)
93
87
  end
94
88
 
95
89
  end
@@ -30,9 +30,6 @@ class EmailAccount
30
30
  belongs_to :user
31
31
  end
32
32
 
33
- Inflector.inflections.irregular 'assignees', 'assignee'
34
- Inflector.inflections.irregular 'assignee', 'assignees'
35
-
36
33
  describe 'related objects' do
37
34
  describe "supporting belongs_to and has_many with camelcased relations" do
38
35
  before do
@@ -42,7 +39,7 @@ describe 'related objects' do
42
39
 
43
40
  it "camelcased style" do
44
41
  t = User.create(:name => "Arkan")
45
- t.email_accounts.create(:name => "Gmail")
42
+ t.email_accounts_relation.create(:name => "Gmail")
46
43
  EmailAccount.first.user.name.should == "Arkan"
47
44
  User.last.email_accounts.last.name.should == "Gmail"
48
45
  end
@@ -61,12 +58,12 @@ describe 'related objects' do
61
58
 
62
59
  it 'relation objects are empty on initialization' do
63
60
  a_task = Task.create
64
- a_task.assignees.all.should.be.empty
61
+ a_task.assignees_relation.all.should.be.empty
65
62
  end
66
63
 
67
64
  it "supports creating related objects directly on parents" do
68
65
  a_task = Task.create(:name => 'Walk the Dog')
69
- a_task.assignees.create(:assignee_name => 'bob')
66
+ a_task.assignees_relation.create(:assignee_name => 'bob')
70
67
  a_task.assignees.count.should == 1
71
68
  a_task.assignees.first.assignee_name.should == 'bob'
72
69
  Assignee.count.should == 1
@@ -84,7 +81,7 @@ describe 'related objects' do
84
81
  assignee_index = 1
85
82
  @tasks << t
86
83
  1.upto(task * 2) do |assignee|
87
- @assignees << t.assignees.create(:assignee_name => "employee #{assignee_index}_assignee_for_task_#{t.id}")
84
+ @assignees << t.assignees_relation.create(:assignee_name => "employee #{assignee_index}_assignee_for_task_#{t.id}")
88
85
  assignee_index += 1
89
86
  end
90
87
  end
@@ -108,7 +105,7 @@ describe 'related objects' do
108
105
  assignee = Assignee.new(:assignee_name => 'Zoe')
109
106
  Task.count.should == 3
110
107
  assignee_count = Task.find(3).assignees.count
111
- Task.find(3).assignees.push(assignee)
108
+ Task.find(3).assignees_relation.push(assignee)
112
109
  Task.find(3).assignees.count.should == assignee_count + 1
113
110
  end
114
111
 
@@ -116,7 +113,7 @@ describe 'related objects' do
116
113
 
117
114
  it "supports creating blank (empty) scratchpad associated objects" do
118
115
  task = Task.create :name => 'watch a movie'
119
- assignee = task.assignees.new
116
+ assignee = task.assignees_relation.new # TODO per Rails convention, this should really be #build, not #new
120
117
  assignee.assignee_name = 'Chloe'
121
118
  assignee.save
122
119
  task.assignees.count.should == 1
@@ -132,7 +129,7 @@ describe 'related objects' do
132
129
 
133
130
  it "allows a child to back-reference its parent" do
134
131
  t = Task.create(:name => "Walk the Dog")
135
- t.assignees.create(:assignee_name => "Rihanna")
132
+ t.assignees_relation.create(:assignee_name => "Rihanna")
136
133
  Assignee.first.task.name.should == "Walk the Dog"
137
134
  end
138
135
 
@@ -146,7 +143,7 @@ describe 'related objects' do
146
143
 
147
144
  describe "basic wiring" do
148
145
  before do
149
- @t1.assignees << @a1
146
+ @t1.assignees_relation << @a1
150
147
  end
151
148
 
152
149
  it "pushing a created assignee gives a task count of 1" do
@@ -164,7 +161,7 @@ describe 'related objects' do
164
161
 
165
162
  describe "when pushing assignees onto two different tasks" do
166
163
  before do
167
- @t2.assignees << @a1
164
+ @t2.assignees_relation << @a1
168
165
  end
169
166
 
170
167
  it "pushing assignees to two different tasks lets the last task have the assignee (count)" do
@@ -186,7 +183,7 @@ describe 'related objects' do
186
183
 
187
184
  describe "directly assigning to child" do
188
185
  it "directly assigning a different task to an assignee changes the assignee's task" do
189
- @a1.task = @t1.id
186
+ @a1.task_id = @t1.id
190
187
  @a1.save
191
188
  @t1.assignees.count.should == 1
192
189
  @t1.assignees.first.assignee_name.should == @a1.assignee_name