deferred_associations 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/Rakefile +27 -26
- data/Readme.markdown +85 -82
- data/VERSION +1 -1
- data/deferred_associations.gemspec +61 -75
- data/init.rb +1 -1
- data/lib/array_to_association_wrapper.rb +0 -0
- data/lib/deferred_associations.rb +0 -0
- data/lib/has_and_belongs_to_many_with_deferred_save.rb +142 -142
- data/lib/has_many_with_deferred_save.rb +10 -1
- data/spec/db/database.yml +21 -21
- data/spec/db/schema.rb +40 -40
- data/spec/has_and_belongs_to_many_with_deferred_save_spec.rb +236 -234
- data/spec/has_many_with_deferred_save_spec.rb +28 -1
- data/spec/models/chair.rb +0 -0
- data/spec/models/door.rb +3 -3
- data/spec/models/person.rb +15 -15
- data/spec/models/room.rb +51 -51
- data/spec/models/table.rb +0 -0
- data/spec/spec_helper.rb +47 -39
- metadata +85 -95
- data/.gitignore +0 -3
- data/.travis.yml +0 -12
- data/gemfiles/ar2.3.14.gemfile +0 -12
- data/gemfiles/ar2.3.14.gemfile.lock +0 -47
- data/gemfiles/ar3.2.3.gemfile +0 -12
- data/gemfiles/ar3.2.3.gemfile.lock +0 -96
- data/spec/.gitignore +0 -2
@@ -16,6 +16,7 @@ module ActiveRecord
|
|
16
16
|
define_obj_setter collection_name
|
17
17
|
define_obj_getter collection_name
|
18
18
|
define_id_setter collection_name
|
19
|
+
define_id_getter collection_name
|
19
20
|
|
20
21
|
define_update_method collection_name
|
21
22
|
define_reload_method collection_name
|
@@ -63,13 +64,21 @@ module ActiveRecord
|
|
63
64
|
collection_singular_ids = "#{collection_name.singularize}_ids"
|
64
65
|
define_method "#{collection_singular_ids}_with_deferred_save=" do |ids|
|
65
66
|
ids = Array.wrap(ids).reject { |id| id.blank? }
|
66
|
-
new_values = self.send("#{collection_name}").klass.find(ids)
|
67
|
+
new_values = self.send("#{collection_name}_without_deferred_save").klass.find(ids)
|
67
68
|
self.send("#{collection_name}=", new_values)
|
68
69
|
end
|
69
70
|
alias_method_chain :"#{collection_singular_ids}=", 'deferred_save'
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
74
|
+
def define_id_getter collection_name
|
75
|
+
collection_singular_ids = "#{collection_name.singularize}_ids"
|
76
|
+
define_method "#{collection_singular_ids}_with_deferred_save" do
|
77
|
+
self.send(collection_name).map { |e| e[:id] }
|
78
|
+
end
|
79
|
+
alias_method_chain :"#{collection_singular_ids}", 'deferred_save'
|
80
|
+
end
|
81
|
+
|
73
82
|
def define_update_method collection_name
|
74
83
|
|
75
84
|
define_method "hmwds_update_#{collection_name}" do
|
data/spec/db/database.yml
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
sqlite3:
|
2
|
-
adapter: sqlite3
|
3
|
-
database: test.sqlite3.db
|
4
|
-
|
5
|
-
sqlite3mem:
|
6
|
-
adapter: sqlite3
|
7
|
-
database: ":memory:"
|
8
|
-
|
9
|
-
postgresql:
|
10
|
-
adapter: postgresql
|
11
|
-
username: postgres
|
12
|
-
password: postgres
|
13
|
-
database: has_and_belongs_to_many_with_deferred_save_test
|
14
|
-
min_messages: ERROR
|
15
|
-
|
16
|
-
mysql:
|
17
|
-
adapter: mysql
|
18
|
-
host: localhost
|
19
|
-
username: root
|
20
|
-
password:
|
21
|
-
database: has_and_belongs_to_many_with_deferred_save_test
|
1
|
+
sqlite3:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: test.sqlite3.db
|
4
|
+
|
5
|
+
sqlite3mem:
|
6
|
+
adapter: sqlite3
|
7
|
+
database: ":memory:"
|
8
|
+
|
9
|
+
postgresql:
|
10
|
+
adapter: postgresql
|
11
|
+
username: postgres
|
12
|
+
password: postgres
|
13
|
+
database: has_and_belongs_to_many_with_deferred_save_test
|
14
|
+
min_messages: ERROR
|
15
|
+
|
16
|
+
mysql:
|
17
|
+
adapter: mysql
|
18
|
+
host: localhost
|
19
|
+
username: root
|
20
|
+
password:
|
21
|
+
database: has_and_belongs_to_many_with_deferred_save_test
|
data/spec/db/schema.rb
CHANGED
@@ -1,40 +1,40 @@
|
|
1
|
-
# This file is autogenerated. Instead of editing this file, please use the
|
2
|
-
# migrations feature of ActiveRecord to incrementally modify your database, and
|
3
|
-
# then regenerate this schema definition.
|
4
|
-
|
5
|
-
ActiveRecord::Schema.define(:version => 1) do
|
6
|
-
|
7
|
-
create_table "people", :force => true do |t|
|
8
|
-
t.column "name", :string
|
9
|
-
end
|
10
|
-
|
11
|
-
create_table "people_rooms", :id => false, :force => true do |t|
|
12
|
-
t.column "person_id", :integer
|
13
|
-
t.column "room_id", :integer
|
14
|
-
end
|
15
|
-
|
16
|
-
create_table "rooms", :force => true do |t|
|
17
|
-
t.column "name", :string
|
18
|
-
t.column "maximum_occupancy", :integer
|
19
|
-
end
|
20
|
-
|
21
|
-
create_table "doors_rooms", :id => false, :force => true do |t|
|
22
|
-
t.column "door_id", :integer
|
23
|
-
t.column "room_id", :integer
|
24
|
-
end
|
25
|
-
|
26
|
-
create_table "doors", :force => true do |t|
|
27
|
-
t.column "name", :string
|
28
|
-
end
|
29
|
-
|
30
|
-
create_table "tables", :force => true do |t|
|
31
|
-
t.column "name", :string
|
32
|
-
t.column "room_id", :integer
|
33
|
-
end
|
34
|
-
|
35
|
-
create_table "chairs", :force => true do |t|
|
36
|
-
t.column "name", :string
|
37
|
-
t.column "table_id", :integer
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
1
|
+
# This file is autogenerated. Instead of editing this file, please use the
|
2
|
+
# migrations feature of ActiveRecord to incrementally modify your database, and
|
3
|
+
# then regenerate this schema definition.
|
4
|
+
|
5
|
+
ActiveRecord::Schema.define(:version => 1) do
|
6
|
+
|
7
|
+
create_table "people", :force => true do |t|
|
8
|
+
t.column "name", :string
|
9
|
+
end
|
10
|
+
|
11
|
+
create_table "people_rooms", :id => false, :force => true do |t|
|
12
|
+
t.column "person_id", :integer
|
13
|
+
t.column "room_id", :integer
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table "rooms", :force => true do |t|
|
17
|
+
t.column "name", :string
|
18
|
+
t.column "maximum_occupancy", :integer
|
19
|
+
end
|
20
|
+
|
21
|
+
create_table "doors_rooms", :id => false, :force => true do |t|
|
22
|
+
t.column "door_id", :integer
|
23
|
+
t.column "room_id", :integer
|
24
|
+
end
|
25
|
+
|
26
|
+
create_table "doors", :force => true do |t|
|
27
|
+
t.column "name", :string
|
28
|
+
end
|
29
|
+
|
30
|
+
create_table "tables", :force => true do |t|
|
31
|
+
t.column "name", :string
|
32
|
+
t.column "room_id", :integer
|
33
|
+
end
|
34
|
+
|
35
|
+
create_table "chairs", :force => true do |t|
|
36
|
+
t.column "name", :string
|
37
|
+
t.column "table_id", :integer
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -1,234 +1,236 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require 'has_and_belongs_to_many_with_deferred_save'
|
3
|
-
|
4
|
-
describe "has_and_belongs_to_many_with_deferred_save" do
|
5
|
-
describe "room maximum_occupancy" do
|
6
|
-
before :all do
|
7
|
-
@people = []
|
8
|
-
@people << Person.create(:name => 'Filbert')
|
9
|
-
@people << Person.create(:name => 'Miguel')
|
10
|
-
@people << Person.create(:name => 'Rainer')
|
11
|
-
@room = Room.new(:maximum_occupancy => 2)
|
12
|
-
end
|
13
|
-
after :all do
|
14
|
-
Person.delete_all
|
15
|
-
Room.delete_all
|
16
|
-
end
|
17
|
-
|
18
|
-
it "passes initial checks" do
|
19
|
-
Room .count.should == 0
|
20
|
-
Person.count.should == 3
|
21
|
-
|
22
|
-
@room.people.should == []
|
23
|
-
@room.people_without_deferred_save.should == []
|
24
|
-
@room.people_without_deferred_save.object_id.should_not ==
|
25
|
-
@room.unsaved_people.object_id
|
26
|
-
end
|
27
|
-
|
28
|
-
it "after adding people to room, it should not have saved anything to the database" do
|
29
|
-
@room.people << @people[0]
|
30
|
-
@room.people << @people[1]
|
31
|
-
|
32
|
-
# Still not saved to the association table!
|
33
|
-
Room.count_by_sql("select count(*) from people_rooms").should == 0
|
34
|
-
@room.people_without_deferred_save.size. should == 0
|
35
|
-
end
|
36
|
-
|
37
|
-
it "but room.people.size should still report the current size of 2" do
|
38
|
-
@room.people.size.should == 2 # 2 because this looks at unsaved_people and not at the database
|
39
|
-
end
|
40
|
-
|
41
|
-
it "after saving the model, the association should be saved in the join table" do
|
42
|
-
@room.save # Only here is it actually saved to the association table!
|
43
|
-
@room.errors.full_messages.should == []
|
44
|
-
Room.count_by_sql("select count(*) from people_rooms").should == 2
|
45
|
-
@room.people.size. should == 2
|
46
|
-
@room.people_without_deferred_save.size. should == 2
|
47
|
-
end
|
48
|
-
|
49
|
-
it "when we try to add a 3rd person, it should add a validation error to the errors object like any other validation error" do
|
50
|
-
lambda { @room.people << @people[2] }.should_not raise_error
|
51
|
-
@room.people.size. should == 3
|
52
|
-
|
53
|
-
Room.count_by_sql("select count(*) from people_rooms").should == 2
|
54
|
-
@room.valid?
|
55
|
-
@room.get_error(:people).should == "This room has reached its maximum occupancy"
|
56
|
-
@room.people.size. should == 3 # Just like with normal attributes that fail validation... the attribute still contains the invalid data but we refuse to save until it is changed to something that is *valid*.
|
57
|
-
end
|
58
|
-
|
59
|
-
it "when we try to save, it should fail, because room.people is still invalid" do
|
60
|
-
@room.save.should == false
|
61
|
-
Room.count_by_sql("select count(*) from people_rooms").should == 2 # It's still not there, because it didn't pass the validation.
|
62
|
-
@room.get_error(:people).should == "This room has reached its maximum occupancy"
|
63
|
-
@room.people.size. should == 3
|
64
|
-
@people.map {|p| p.reload; p.rooms.size}.should == [1, 1, 0]
|
65
|
-
end
|
66
|
-
|
67
|
-
it "when we reload, it should go back to only having 2 people in the room" do
|
68
|
-
@room.reload
|
69
|
-
@room.people.size. should == 2
|
70
|
-
@room.people_without_deferred_save.size. should == 2
|
71
|
-
@people.map {|p| p.reload; p.rooms.size}. should == [1, 1, 0]
|
72
|
-
end
|
73
|
-
|
74
|
-
it "if they try to go around our accessors and use the original accessors, then (and only then) will the exception be raised in before_adding_person..." do
|
75
|
-
lambda do
|
76
|
-
@room.people_without_deferred_save << @people[2]
|
77
|
-
end.should raise_error(RuntimeError)
|
78
|
-
end
|
79
|
-
|
80
|
-
it "lets you bypass the validation on Room if we add the association from the other side (person.rooms <<)?" do
|
81
|
-
@people[2].rooms << @room
|
82
|
-
@people[2].rooms.size.should == 1
|
83
|
-
|
84
|
-
# Adding it from one direction does not add it to the other object's association (@room.people), so the validation passes.
|
85
|
-
@room.reload.people.size.should == 2
|
86
|
-
@people[2].valid?
|
87
|
-
@people[2].errors.full_messages.should == []
|
88
|
-
@people[2].save.should == true
|
89
|
-
|
90
|
-
# It is only after reloading that @room.people has this 3rd object, causing it to be invalid, and by then it's too late to do anything about it.
|
91
|
-
@room.reload.people.size.should == 3
|
92
|
-
@room.valid?.should == false
|
93
|
-
end
|
94
|
-
|
95
|
-
it "only if you add the validation to both sides, can you ensure that the size of the association does not exceed some limit" do
|
96
|
-
@room.reload.people.size.should == 3
|
97
|
-
@room.people.delete(@people[2])
|
98
|
-
@room.save.should == true
|
99
|
-
@room.reload.people.size.should == 2
|
100
|
-
@people[2].reload.rooms.size.should == 0
|
101
|
-
|
102
|
-
obj = @people[2]
|
103
|
-
obj.do_extra_validation = true
|
104
|
-
|
105
|
-
@people[2].rooms << @room
|
106
|
-
@people[2].rooms.size.should == 1
|
107
|
-
|
108
|
-
@room.reload.people.size.should == 2
|
109
|
-
@people[2].valid?.should be_false
|
110
|
-
@people[2].get_error(:rooms).should == "This room has reached its maximum occupancy"
|
111
|
-
@room.reload.people.size.should == 2
|
112
|
-
end
|
113
|
-
|
114
|
-
it "still lets you do find" do
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
@room.
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
@room.
|
143
|
-
|
144
|
-
@room.
|
145
|
-
@room.
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
@room.
|
162
|
-
@room.
|
163
|
-
@room.
|
164
|
-
Room.find(@room.id)
|
165
|
-
@room.
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
@room
|
171
|
-
@room.
|
172
|
-
@room.save
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
Room.find(@room.id)
|
178
|
-
@room.
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
@room
|
184
|
-
@room.
|
185
|
-
@room.
|
186
|
-
@room.
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
@room = Room.find(@room.id)
|
191
|
-
@room.people
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
@door.
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
@door.rooms.
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
end
|
1
|
+
require "spec_helper"
|
2
|
+
require 'has_and_belongs_to_many_with_deferred_save'
|
3
|
+
|
4
|
+
describe "has_and_belongs_to_many_with_deferred_save" do
|
5
|
+
describe "room maximum_occupancy" do
|
6
|
+
before :all do
|
7
|
+
@people = []
|
8
|
+
@people << Person.create(:name => 'Filbert')
|
9
|
+
@people << Person.create(:name => 'Miguel')
|
10
|
+
@people << Person.create(:name => 'Rainer')
|
11
|
+
@room = Room.new(:maximum_occupancy => 2)
|
12
|
+
end
|
13
|
+
after :all do
|
14
|
+
Person.delete_all
|
15
|
+
Room.delete_all
|
16
|
+
end
|
17
|
+
|
18
|
+
it "passes initial checks" do
|
19
|
+
Room .count.should == 0
|
20
|
+
Person.count.should == 3
|
21
|
+
|
22
|
+
@room.people.should == []
|
23
|
+
@room.people_without_deferred_save.should == []
|
24
|
+
@room.people_without_deferred_save.object_id.should_not ==
|
25
|
+
@room.unsaved_people.object_id
|
26
|
+
end
|
27
|
+
|
28
|
+
it "after adding people to room, it should not have saved anything to the database" do
|
29
|
+
@room.people << @people[0]
|
30
|
+
@room.people << @people[1]
|
31
|
+
|
32
|
+
# Still not saved to the association table!
|
33
|
+
Room.count_by_sql("select count(*) from people_rooms").should == 0
|
34
|
+
@room.people_without_deferred_save.size. should == 0
|
35
|
+
end
|
36
|
+
|
37
|
+
it "but room.people.size should still report the current size of 2" do
|
38
|
+
@room.people.size.should == 2 # 2 because this looks at unsaved_people and not at the database
|
39
|
+
end
|
40
|
+
|
41
|
+
it "after saving the model, the association should be saved in the join table" do
|
42
|
+
@room.save # Only here is it actually saved to the association table!
|
43
|
+
@room.errors.full_messages.should == []
|
44
|
+
Room.count_by_sql("select count(*) from people_rooms").should == 2
|
45
|
+
@room.people.size. should == 2
|
46
|
+
@room.people_without_deferred_save.size. should == 2
|
47
|
+
end
|
48
|
+
|
49
|
+
it "when we try to add a 3rd person, it should add a validation error to the errors object like any other validation error" do
|
50
|
+
lambda { @room.people << @people[2] }.should_not raise_error
|
51
|
+
@room.people.size. should == 3
|
52
|
+
|
53
|
+
Room.count_by_sql("select count(*) from people_rooms").should == 2
|
54
|
+
@room.valid?
|
55
|
+
@room.get_error(:people).should == "This room has reached its maximum occupancy"
|
56
|
+
@room.people.size. should == 3 # Just like with normal attributes that fail validation... the attribute still contains the invalid data but we refuse to save until it is changed to something that is *valid*.
|
57
|
+
end
|
58
|
+
|
59
|
+
it "when we try to save, it should fail, because room.people is still invalid" do
|
60
|
+
@room.save.should == false
|
61
|
+
Room.count_by_sql("select count(*) from people_rooms").should == 2 # It's still not there, because it didn't pass the validation.
|
62
|
+
@room.get_error(:people).should == "This room has reached its maximum occupancy"
|
63
|
+
@room.people.size. should == 3
|
64
|
+
@people.map {|p| p.reload; p.rooms.size}.should == [1, 1, 0]
|
65
|
+
end
|
66
|
+
|
67
|
+
it "when we reload, it should go back to only having 2 people in the room" do
|
68
|
+
@room.reload
|
69
|
+
@room.people.size. should == 2
|
70
|
+
@room.people_without_deferred_save.size. should == 2
|
71
|
+
@people.map {|p| p.reload; p.rooms.size}. should == [1, 1, 0]
|
72
|
+
end
|
73
|
+
|
74
|
+
it "if they try to go around our accessors and use the original accessors, then (and only then) will the exception be raised in before_adding_person..." do
|
75
|
+
lambda do
|
76
|
+
@room.people_without_deferred_save << @people[2]
|
77
|
+
end.should raise_error(RuntimeError)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "lets you bypass the validation on Room if we add the association from the other side (person.rooms <<)?" do
|
81
|
+
@people[2].rooms << @room
|
82
|
+
@people[2].rooms.size.should == 1
|
83
|
+
|
84
|
+
# Adding it from one direction does not add it to the other object's association (@room.people), so the validation passes.
|
85
|
+
@room.reload.people.size.should == 2
|
86
|
+
@people[2].valid?
|
87
|
+
@people[2].errors.full_messages.should == []
|
88
|
+
@people[2].save.should == true
|
89
|
+
|
90
|
+
# It is only after reloading that @room.people has this 3rd object, causing it to be invalid, and by then it's too late to do anything about it.
|
91
|
+
@room.reload.people.size.should == 3
|
92
|
+
@room.valid?.should == false
|
93
|
+
end
|
94
|
+
|
95
|
+
it "only if you add the validation to both sides, can you ensure that the size of the association does not exceed some limit" do
|
96
|
+
@room.reload.people.size.should == 3
|
97
|
+
@room.people.delete(@people[2])
|
98
|
+
@room.save.should == true
|
99
|
+
@room.reload.people.size.should == 2
|
100
|
+
@people[2].reload.rooms.size.should == 0
|
101
|
+
|
102
|
+
obj = @people[2]
|
103
|
+
obj.do_extra_validation = true
|
104
|
+
|
105
|
+
@people[2].rooms << @room
|
106
|
+
@people[2].rooms.size.should == 1
|
107
|
+
|
108
|
+
@room.reload.people.size.should == 2
|
109
|
+
@people[2].valid?.should be_false
|
110
|
+
@people[2].get_error(:rooms).should == "This room has reached its maximum occupancy"
|
111
|
+
@room.reload.people.size.should == 2
|
112
|
+
end
|
113
|
+
|
114
|
+
it "still lets you do find" do
|
115
|
+
if ar4?
|
116
|
+
@room.people2.where(:name => 'Filbert').first.should == @people[0]
|
117
|
+
@room.people_without_deferred_save.where(:name => 'Filbert').first.should == @people[0]
|
118
|
+
@room.people.where(:name => 'Filbert').first.should == @people[0]
|
119
|
+
else
|
120
|
+
@room.people2. find(:first, :conditions => {:name => 'Filbert'}).should == @people[0]
|
121
|
+
@room.people_without_deferred_save.find(:first, :conditions => {:name => 'Filbert'}).should == @people[0]
|
122
|
+
@room.people2.first(:conditions => {:name => 'Filbert'}).should == @people[0]
|
123
|
+
@room.people_without_deferred_save.first(:conditions => {:name => 'Filbert'}).should == @people[0]
|
124
|
+
|
125
|
+
@room.people.find(:first, :conditions => {:name => 'Filbert'}).should == @people[0]
|
126
|
+
@room.people.first(:conditions => {:name => 'Filbert'}). should == @people[0]
|
127
|
+
@room.people.last(:conditions => {:name => 'Filbert'}). should == @people[0]
|
128
|
+
end
|
129
|
+
|
130
|
+
@room.people.first. should == @people[0]
|
131
|
+
@room.people.last. should == @people[1] # @people[2] was removed before
|
132
|
+
@room.people.find_by_name('Filbert'). should == @people[0]
|
133
|
+
@room.people_without_deferred_save.find_by_name('Filbert').should == @people[0]
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should be dumpable with Marshal" do
|
137
|
+
lambda { Marshal.dump(@room.people) }.should_not raise_exception
|
138
|
+
lambda { Marshal.dump(Room.new.people) }.should_not raise_exception
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should detect difference in association" do
|
142
|
+
@room = Room.find(@room.id)
|
143
|
+
@room.bs_diff_before_module.should be_nil
|
144
|
+
@room.bs_diff_after_module.should be_nil
|
145
|
+
@room.bs_diff_method.should be_nil
|
146
|
+
|
147
|
+
@room.people.size.should == 2
|
148
|
+
@room.people = [@room.people[0]]
|
149
|
+
@room.save.should be_true
|
150
|
+
|
151
|
+
@room.bs_diff_before_module.should be_true
|
152
|
+
@room.bs_diff_after_module.should be_true
|
153
|
+
if ar2?
|
154
|
+
@room.bs_diff_method.should be_true
|
155
|
+
else
|
156
|
+
@room.bs_diff_method.should be_nil # Rails 3.2: nil (before_save filter is not supported)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should act like original habtm when using ID array with array manipulation" do
|
161
|
+
@room = Room.find(@room.id)
|
162
|
+
@room.people = [@people[0]]
|
163
|
+
@room.save
|
164
|
+
@room = Room.find(@room.id) # we don't want to let id and object setters interfere with each other
|
165
|
+
@room.people2_ids << @people[1].id
|
166
|
+
@room.people2_ids.should == [@people[0].id] # ID array manipulation is ignored
|
167
|
+
|
168
|
+
@room.person_ids.size.should == 1
|
169
|
+
@room.person_ids << @people[1].id
|
170
|
+
@room.person_ids.should == [@people[0].id]
|
171
|
+
Room.find(@room.id).person_ids.should == [@people[0].id]
|
172
|
+
@room.save.should be_true
|
173
|
+
Room.find(@room.id).person_ids.should == [@people[0].id] # ID array manipulation is ignored, too
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should work with id setters" do
|
177
|
+
@room = Room.find(@room.id)
|
178
|
+
@room.people = [@people[0], @people[1]]
|
179
|
+
@room.save
|
180
|
+
@room = Room.find(@room.id)
|
181
|
+
@room.person_ids.should == [@people[0].id, @people[1].id]
|
182
|
+
@room.person_ids = [@people[1].id]
|
183
|
+
@room.person_ids.should == [@people[1].id]
|
184
|
+
Room.find(@room.id).person_ids.should == [@people[0].id,@people[1].id]
|
185
|
+
@room.save.should be_true
|
186
|
+
Room.find(@room.id).person_ids.should == [@people[1].id]
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should work with multiple id setters and object setters" do
|
190
|
+
@room = Room.find(@room.id)
|
191
|
+
@room.people = [@people[0]]
|
192
|
+
@room.person_ids = [@people[0].id, @people[1].id]
|
193
|
+
@room.people = [@people[1]]
|
194
|
+
@room.person_ids = [@people[0].id, @people[1].id]
|
195
|
+
@room.people = [@people[1]]
|
196
|
+
@room.save
|
197
|
+
@room = Room.find(@room.id)
|
198
|
+
@room.people.should == [@people[1]]
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should give klass in AR 3/4" do
|
202
|
+
unless ar2?
|
203
|
+
@room.people.klass.should == Person
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should give aliased_table_name in AR 2.3" do
|
208
|
+
if ar2?
|
209
|
+
@room.people.aliased_table_name.should == "people"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "doors" do
|
215
|
+
before :all do
|
216
|
+
@rooms = []
|
217
|
+
@rooms << Room.create(:name => 'Kitchen', :maximum_occupancy => 1)
|
218
|
+
@rooms << Room.create(:name => 'Dining room', :maximum_occupancy => 10)
|
219
|
+
@door = Door.new(:name => 'Kitchen-Dining-room door')
|
220
|
+
end
|
221
|
+
|
222
|
+
it "passes initial checks" do
|
223
|
+
Room.count.should == 2
|
224
|
+
Door.count.should == 0
|
225
|
+
|
226
|
+
@door.rooms.should == []
|
227
|
+
@door.rooms_without_deferred_save.should == []
|
228
|
+
end
|
229
|
+
|
230
|
+
it "the association has an include? method" do
|
231
|
+
@door.rooms << @rooms[0]
|
232
|
+
@door.rooms.include?(@rooms[0]).should be_true
|
233
|
+
@door.rooms.include?(@rooms[1]).should be_false
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|