datamapper 0.3.2 → 0.9.3
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/History.txt +0 -0
- data/Manifest.txt +5 -0
- data/README.txt +11 -0
- data/Rakefile +70 -0
- data/lib/datamapper.rb +8 -0
- metadata +152 -319
- data/CHANGELOG +0 -145
- data/FAQ +0 -96
- data/MIT-LICENSE +0 -22
- data/QUICKLINKS +0 -12
- data/README +0 -105
- data/environment.rb +0 -62
- data/example.rb +0 -156
- data/lib/data_mapper.rb +0 -88
- data/lib/data_mapper/adapters/abstract_adapter.rb +0 -43
- data/lib/data_mapper/adapters/data_object_adapter.rb +0 -480
- data/lib/data_mapper/adapters/mysql_adapter.rb +0 -72
- data/lib/data_mapper/adapters/postgresql_adapter.rb +0 -258
- data/lib/data_mapper/adapters/sql/coersion.rb +0 -134
- data/lib/data_mapper/adapters/sql/commands/load_command.rb +0 -545
- data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +0 -34
- data/lib/data_mapper/adapters/sql/mappings/column.rb +0 -279
- data/lib/data_mapper/adapters/sql/mappings/conditions.rb +0 -172
- data/lib/data_mapper/adapters/sql/mappings/schema.rb +0 -60
- data/lib/data_mapper/adapters/sql/mappings/table.rb +0 -459
- data/lib/data_mapper/adapters/sql/quoting.rb +0 -24
- data/lib/data_mapper/adapters/sqlite3_adapter.rb +0 -159
- data/lib/data_mapper/associations.rb +0 -106
- data/lib/data_mapper/associations/belongs_to_association.rb +0 -160
- data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +0 -437
- data/lib/data_mapper/associations/has_many_association.rb +0 -283
- data/lib/data_mapper/associations/has_n_association.rb +0 -143
- data/lib/data_mapper/associations/reference.rb +0 -47
- data/lib/data_mapper/attributes.rb +0 -73
- data/lib/data_mapper/auto_migrations.rb +0 -36
- data/lib/data_mapper/base.rb +0 -17
- data/lib/data_mapper/callbacks.rb +0 -107
- data/lib/data_mapper/context.rb +0 -112
- data/lib/data_mapper/database.rb +0 -234
- data/lib/data_mapper/dependency_queue.rb +0 -28
- data/lib/data_mapper/embedded_value.rb +0 -145
- data/lib/data_mapper/identity_map.rb +0 -47
- data/lib/data_mapper/is/tree.rb +0 -121
- data/lib/data_mapper/migration.rb +0 -155
- data/lib/data_mapper/persistence.rb +0 -852
- data/lib/data_mapper/property.rb +0 -310
- data/lib/data_mapper/query.rb +0 -164
- data/lib/data_mapper/support/blank.rb +0 -35
- data/lib/data_mapper/support/connection_pool.rb +0 -117
- data/lib/data_mapper/support/enumerable.rb +0 -35
- data/lib/data_mapper/support/errors.rb +0 -16
- data/lib/data_mapper/support/inflector.rb +0 -265
- data/lib/data_mapper/support/object.rb +0 -54
- data/lib/data_mapper/support/serialization.rb +0 -96
- data/lib/data_mapper/support/silence.rb +0 -10
- data/lib/data_mapper/support/string.rb +0 -72
- data/lib/data_mapper/support/struct.rb +0 -7
- data/lib/data_mapper/support/symbol.rb +0 -82
- data/lib/data_mapper/support/typed_set.rb +0 -65
- data/lib/data_mapper/types/base.rb +0 -44
- data/lib/data_mapper/types/string.rb +0 -34
- data/lib/data_mapper/validatable_extensions/errors.rb +0 -12
- data/lib/data_mapper/validatable_extensions/macros.rb +0 -7
- data/lib/data_mapper/validatable_extensions/validatable_instance_methods.rb +0 -62
- data/lib/data_mapper/validatable_extensions/validation_base.rb +0 -18
- data/lib/data_mapper/validatable_extensions/validations/formats/email.rb +0 -43
- data/lib/data_mapper/validatable_extensions/validations/validates_acceptance_of.rb +0 -7
- data/lib/data_mapper/validatable_extensions/validations/validates_confirmation_of.rb +0 -7
- data/lib/data_mapper/validatable_extensions/validations/validates_each.rb +0 -7
- data/lib/data_mapper/validatable_extensions/validations/validates_format_of.rb +0 -28
- data/lib/data_mapper/validatable_extensions/validations/validates_length_of.rb +0 -15
- data/lib/data_mapper/validatable_extensions/validations/validates_numericality_of.rb +0 -7
- data/lib/data_mapper/validatable_extensions/validations/validates_presence_of.rb +0 -7
- data/lib/data_mapper/validatable_extensions/validations/validates_true_for.rb +0 -7
- data/lib/data_mapper/validatable_extensions/validations/validates_uniqueness_of.rb +0 -40
- data/lib/data_mapper/validations.rb +0 -20
- data/lib/data_mapper/validations/number_validator.rb +0 -40
- data/lib/data_mapper/validations/string_validator.rb +0 -20
- data/lib/data_mapper/validations/validator.rb +0 -13
- data/performance.rb +0 -307
- data/plugins/can_has_sphinx/LICENSE +0 -23
- data/plugins/can_has_sphinx/README +0 -4
- data/plugins/can_has_sphinx/REVISION +0 -1
- data/plugins/can_has_sphinx/Rakefile +0 -22
- data/plugins/can_has_sphinx/init.rb +0 -1
- data/plugins/can_has_sphinx/install.rb +0 -1
- data/plugins/can_has_sphinx/lib/acts_as_sphinx.rb +0 -123
- data/plugins/can_has_sphinx/lib/sphinx.rb +0 -460
- data/plugins/can_has_sphinx/scripts/sphinx.sh +0 -47
- data/plugins/can_has_sphinx/tasks/acts_as_sphinx_tasks.rake +0 -41
- data/profile_data_mapper.rb +0 -40
- data/rakefile.rb +0 -159
- data/spec/acts_as_tree_spec.rb +0 -67
- data/spec/adapters/data_object_adapter_spec.rb +0 -31
- data/spec/associations/belongs_to_association_spec.rb +0 -98
- data/spec/associations/has_and_belongs_to_many_association_spec.rb +0 -377
- data/spec/associations/has_many_association_spec.rb +0 -337
- data/spec/attributes_spec.rb +0 -52
- data/spec/auto_migrations_spec.rb +0 -101
- data/spec/callbacks_spec.rb +0 -186
- data/spec/can_has_sphinx.rb +0 -5
- data/spec/coersion_spec.rb +0 -41
- data/spec/column_spec.rb +0 -114
- data/spec/count_command_spec.rb +0 -45
- data/spec/database_spec.rb +0 -18
- data/spec/dataobjects_spec.rb +0 -27
- data/spec/delete_command_spec.rb +0 -11
- data/spec/dependency_spec.rb +0 -29
- data/spec/embedded_value_spec.rb +0 -161
- data/spec/fixtures/animals.yaml +0 -33
- data/spec/fixtures/animals_exhibits.yaml +0 -2
- data/spec/fixtures/careers.yaml +0 -5
- data/spec/fixtures/comments.yaml +0 -1
- data/spec/fixtures/exhibits.yaml +0 -90
- data/spec/fixtures/fruit.yaml +0 -6
- data/spec/fixtures/people.yaml +0 -37
- data/spec/fixtures/posts.yaml +0 -3
- data/spec/fixtures/projects.yaml +0 -13
- data/spec/fixtures/sections.yaml +0 -5
- data/spec/fixtures/serializers.yaml +0 -6
- data/spec/fixtures/tasks.yaml +0 -6
- data/spec/fixtures/tasks_tasks.yaml +0 -2
- data/spec/fixtures/tomatoes.yaml +0 -1
- data/spec/fixtures/users.yaml +0 -1
- data/spec/fixtures/zoos.yaml +0 -24
- data/spec/is_a_tree_spec.rb +0 -149
- data/spec/legacy_spec.rb +0 -16
- data/spec/load_command_spec.rb +0 -322
- data/spec/magic_columns_spec.rb +0 -26
- data/spec/migration_spec.rb +0 -267
- data/spec/mock_adapter.rb +0 -20
- data/spec/models/animal.rb +0 -12
- data/spec/models/candidate.rb +0 -8
- data/spec/models/career.rb +0 -7
- data/spec/models/chain.rb +0 -8
- data/spec/models/comment.rb +0 -6
- data/spec/models/exhibit.rb +0 -14
- data/spec/models/fence.rb +0 -7
- data/spec/models/fruit.rb +0 -8
- data/spec/models/job.rb +0 -8
- data/spec/models/person.rb +0 -30
- data/spec/models/post.rb +0 -14
- data/spec/models/project.rb +0 -41
- data/spec/models/sales_person.rb +0 -5
- data/spec/models/section.rb +0 -8
- data/spec/models/serializer.rb +0 -5
- data/spec/models/task.rb +0 -9
- data/spec/models/tomato.rb +0 -27
- data/spec/models/user.rb +0 -12
- data/spec/models/zoo.rb +0 -13
- data/spec/natural_key_spec.rb +0 -36
- data/spec/paranoia_spec.rb +0 -38
- data/spec/persistence_spec.rb +0 -479
- data/spec/postgres_spec.rb +0 -96
- data/spec/property_spec.rb +0 -151
- data/spec/query_spec.rb +0 -77
- data/spec/save_command_spec.rb +0 -94
- data/spec/schema_spec.rb +0 -8
- data/spec/serialize_spec.rb +0 -19
- data/spec/single_table_inheritance_spec.rb +0 -43
- data/spec/spec_helper.rb +0 -45
- data/spec/support/blank_spec.rb +0 -8
- data/spec/support/inflector_spec.rb +0 -41
- data/spec/support/object_spec.rb +0 -9
- data/spec/support/serialization_spec.rb +0 -61
- data/spec/support/silence_spec.rb +0 -15
- data/spec/support/string_spec.rb +0 -7
- data/spec/support/struct_spec.rb +0 -12
- data/spec/support/typed_set_spec.rb +0 -66
- data/spec/symbolic_operators_spec.rb +0 -27
- data/spec/table_spec.rb +0 -79
- data/spec/types/string.rb +0 -81
- data/spec/validates_confirmation_of_spec.rb +0 -55
- data/spec/validates_format_of_spec.rb +0 -78
- data/spec/validates_length_of_spec.rb +0 -117
- data/spec/validates_uniqueness_of_spec.rb +0 -92
- data/spec/validations/number_validator.rb +0 -59
- data/spec/validations/string_validator.rb +0 -14
- data/spec/validations_spec.rb +0 -141
- data/tasks/fixtures.rb +0 -53
|
@@ -1,377 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + "/../spec_helper"
|
|
2
|
-
|
|
3
|
-
describe DataMapper::Associations::HasAndBelongsToManyAssociation do
|
|
4
|
-
|
|
5
|
-
before(:all) do
|
|
6
|
-
fixtures(:animals)
|
|
7
|
-
fixtures(:exhibits)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
before(:each) do
|
|
11
|
-
@amazonia = Exhibit.first :name => 'Amazonia'
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "should generate the SQL for a join statement" do
|
|
15
|
-
animals_association = database(:mock).schema[Exhibit].associations.find { |a| a.name == :animals }
|
|
16
|
-
|
|
17
|
-
animals_association.to_sql.should == <<-EOS.compress_lines
|
|
18
|
-
JOIN `animals_exhibits` ON `animals_exhibits`.`exhibit_id` = `exhibits`.`id`
|
|
19
|
-
JOIN `animals` ON `animals`.`id` = `animals_exhibits`.`animal_id`
|
|
20
|
-
EOS
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "should load associations" do
|
|
24
|
-
database do
|
|
25
|
-
froggy = Animal.first(:name => 'Frog')
|
|
26
|
-
froggy.exhibits.size.should == 1
|
|
27
|
-
froggy.exhibits.first.should == Exhibit.first(:name => 'Amazonia')
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it 'has an animals association' do
|
|
32
|
-
[@amazonia, Exhibit.new].each do |exhibit|
|
|
33
|
-
exhibit.animals.class.should == DataMapper::Associations::HasAndBelongsToManyAssociation::Set
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'has many animals' do
|
|
38
|
-
@amazonia.animals.size.should == 1
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it 'should load associations magically' do
|
|
42
|
-
Exhibit.all.each do |exhibit|
|
|
43
|
-
exhibit.animals.each do |animal|
|
|
44
|
-
animal.exhibits.should include(exhibit)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it 'should allow association of additional objects' do
|
|
50
|
-
buffalo = Animal.create(:name => "Buffalo")
|
|
51
|
-
@amazonia.animals << buffalo
|
|
52
|
-
@amazonia.animals.size.should == 2
|
|
53
|
-
@amazonia.save!
|
|
54
|
-
@amazonia.reload!
|
|
55
|
-
@amazonia.animals.should have(2).entries
|
|
56
|
-
|
|
57
|
-
other = Exhibit[@amazonia.id]
|
|
58
|
-
other.animals.should have(2).entries
|
|
59
|
-
|
|
60
|
-
@amazonia.animals.delete(buffalo).should_not be_nil
|
|
61
|
-
@amazonia.animals.should be_dirty
|
|
62
|
-
@amazonia.save!
|
|
63
|
-
|
|
64
|
-
other = Exhibit[@amazonia.id]
|
|
65
|
-
other.animals.should have(1).entries
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it "should allow association of additional objects (CLEAN)" do
|
|
69
|
-
# pending "http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/92"
|
|
70
|
-
|
|
71
|
-
ted = Exhibit.create(:name => 'Ted')
|
|
72
|
-
ted.should_not be_dirty
|
|
73
|
-
|
|
74
|
-
zest = Animal.create(:name => 'Zest')
|
|
75
|
-
zest.should_not be_dirty
|
|
76
|
-
|
|
77
|
-
ted.animals << zest
|
|
78
|
-
ted.should be_dirty
|
|
79
|
-
ted.save
|
|
80
|
-
|
|
81
|
-
ted.reload!
|
|
82
|
-
ted.should_not be_dirty
|
|
83
|
-
ted.should have(1).animals
|
|
84
|
-
|
|
85
|
-
ted2 = Exhibit[ted.key]
|
|
86
|
-
ted2.should_not be_dirty
|
|
87
|
-
ted2.should have(1).animals
|
|
88
|
-
|
|
89
|
-
ted2.destroy!
|
|
90
|
-
zest.destroy!
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
it 'should allow you to fill and clear an association' do
|
|
94
|
-
marcy = Exhibit.create(:name => 'marcy')
|
|
95
|
-
|
|
96
|
-
Animal.all.each do |animal|
|
|
97
|
-
marcy.animals << animal
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
marcy.save.should eql(true)
|
|
101
|
-
marcy.should have(Animal.count).animals
|
|
102
|
-
|
|
103
|
-
marcy.animals.clear
|
|
104
|
-
marcy.should have(0).animals
|
|
105
|
-
|
|
106
|
-
marcy.save.should eql(true)
|
|
107
|
-
|
|
108
|
-
marcys_stand_in = Exhibit[marcy.id]
|
|
109
|
-
marcys_stand_in.should have(0).animals
|
|
110
|
-
|
|
111
|
-
marcy.destroy!
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
it 'should allow you to delete a specific association member' do
|
|
115
|
-
walter = Exhibit.create(:name => 'walter')
|
|
116
|
-
|
|
117
|
-
Animal.all.each do |animal|
|
|
118
|
-
walter.animals << animal
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
walter.save.should eql(true)
|
|
122
|
-
walter.should have(Animal.count).animals
|
|
123
|
-
|
|
124
|
-
delete_me = walter.animals.first
|
|
125
|
-
walter.animals.delete(delete_me).should eql(delete_me)
|
|
126
|
-
walter.animals.delete(delete_me).should eql(nil)
|
|
127
|
-
|
|
128
|
-
walter.should have(Animal.count - 1).animals
|
|
129
|
-
walter.save.should eql(true)
|
|
130
|
-
|
|
131
|
-
walters_stand_in = Exhibit[walter.id]
|
|
132
|
-
walters_stand_in.animals.size.should eql(walter.animals.size)
|
|
133
|
-
|
|
134
|
-
walter.destroy!
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it "should allow updates to associations using association_keys=" do
|
|
138
|
-
# pending "http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/109-associations-should-support-association_keys-methods"
|
|
139
|
-
database(:default) do
|
|
140
|
-
meerkat = Animal.create(:name => "Meerkat")
|
|
141
|
-
dunes = Exhibit.create(:name => "Dunes")
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
dunes.animals.should be_empty
|
|
145
|
-
dunes.send(:animals_keys=, meerkat.key)
|
|
146
|
-
dunes.save.should be_true
|
|
147
|
-
|
|
148
|
-
dunes.should have(1).animals
|
|
149
|
-
dunes.animals.should include(meerkat)
|
|
150
|
-
|
|
151
|
-
dunes.reload!
|
|
152
|
-
dunes.should have(1).animals
|
|
153
|
-
|
|
154
|
-
dunes.destroy!
|
|
155
|
-
meerkat.destroy!
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it "should allow you to 'append' multiple associated objects at once" do
|
|
160
|
-
dunes = Exhibit.create(:name => 'Dunes')
|
|
161
|
-
|
|
162
|
-
lambda { dunes.animals << @amazonia.animals }.should_not raise_error(ArgumentError)
|
|
163
|
-
lambda { dunes.animals << Animal.all }.should_not raise_error(ArgumentError)
|
|
164
|
-
|
|
165
|
-
dunes.destroy!
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
it "should raise an error when attempting to associate an object not of the correct type (assuming added model doesn't inherit from the correct type)" do
|
|
169
|
-
# pending("see: http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/91")
|
|
170
|
-
@amazonia.animals.should_not be_empty
|
|
171
|
-
chuck = Person.new(:name => "Chuck")
|
|
172
|
-
|
|
173
|
-
## InvalidRecord isn't the error we should use here....needs to be changed
|
|
174
|
-
lambda { @amazonia.animals << chuck }.should raise_error(ArgumentError)
|
|
175
|
-
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
it "should associate an object which has inherited from the correct type into an association" do
|
|
179
|
-
# pending("see: http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/91")
|
|
180
|
-
programmer = Career.first(:name => 'Programmer')
|
|
181
|
-
programmer.followers.should_not be_empty
|
|
182
|
-
|
|
183
|
-
sales_person = SalesPerson.new(:name => 'Chuck')
|
|
184
|
-
|
|
185
|
-
lambda { programmer.followers << sales_person }.should_not raise_error(ArgumentError)
|
|
186
|
-
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
it "should correctly handle dependent associations ~cascading destroy~ (:destroy)" do
|
|
190
|
-
class Chain
|
|
191
|
-
has_and_belongs_to_many :chains, :dependent => :destroy
|
|
192
|
-
end
|
|
193
|
-
Chain.auto_migrate!
|
|
194
|
-
|
|
195
|
-
chain = Chain.create(:name => "1")
|
|
196
|
-
chain.chains << Chain.create(:name => "2")
|
|
197
|
-
chain.chains << Chain.create(:name => "3")
|
|
198
|
-
chain.chains << Chain.create(:name => "4")
|
|
199
|
-
chain.save
|
|
200
|
-
chain4 = Chain.create(:name => "5")
|
|
201
|
-
chain.chains.first.chains << chain4
|
|
202
|
-
chain.chains.first.save
|
|
203
|
-
chain4.chains << Chain.first(:name => "3")
|
|
204
|
-
chain4.save
|
|
205
|
-
chain = Chain[chain.key]
|
|
206
|
-
|
|
207
|
-
chain.destroy!
|
|
208
|
-
Chain.first(:name => "2").should be_nil
|
|
209
|
-
Chain.first(:name => "3").should be_nil
|
|
210
|
-
Chain.first(:name => "4").should be_nil
|
|
211
|
-
Chain.first(:name => "5").should be_nil
|
|
212
|
-
|
|
213
|
-
Chain.delete_all
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
it "should correctly handle dependent associations ~no cascade~ (:delete)" do
|
|
217
|
-
class Chain
|
|
218
|
-
has_and_belongs_to_many :chains, :dependent => :delete
|
|
219
|
-
end
|
|
220
|
-
Chain.auto_migrate!
|
|
221
|
-
|
|
222
|
-
chain = Chain.create(:name => "1")
|
|
223
|
-
chain.chains << Chain.create(:name => "2")
|
|
224
|
-
chain.chains << Chain.create(:name => "3")
|
|
225
|
-
chain.chains << Chain.create(:name => "4")
|
|
226
|
-
chain.save
|
|
227
|
-
chain5 = Chain.create(:name => "5")
|
|
228
|
-
chain.chains.first.chains << chain5
|
|
229
|
-
chain.chains.first.save
|
|
230
|
-
chain = Chain[chain.key]
|
|
231
|
-
|
|
232
|
-
chain.destroy!
|
|
233
|
-
Chain.first(:name => "2").should be_nil
|
|
234
|
-
Chain.first(:name => "3").should be_nil
|
|
235
|
-
Chain.first(:name => "4").should be_nil
|
|
236
|
-
Chain.first(:name => "5").should_not be_nil
|
|
237
|
-
|
|
238
|
-
Chain.delete_all
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
it "should correctly handle dependent associations (:protect)" do
|
|
242
|
-
class Chain
|
|
243
|
-
has_and_belongs_to_many :chains, :dependent => :protect
|
|
244
|
-
end
|
|
245
|
-
Chain.auto_migrate!
|
|
246
|
-
|
|
247
|
-
chain = Chain.create(:name => "1")
|
|
248
|
-
chain.chains << Chain.create(:name => "2")
|
|
249
|
-
chain.chains << Chain.create(:name => "3")
|
|
250
|
-
chain.chains << Chain.create(:name => "4")
|
|
251
|
-
chain.save
|
|
252
|
-
chain4 = Chain.create(:name => "5")
|
|
253
|
-
chain.chains.first.chains << chain4
|
|
254
|
-
chain.chains.first.save
|
|
255
|
-
chain = Chain[chain.key]
|
|
256
|
-
|
|
257
|
-
lambda { chain.destroy! }.should raise_error(DataMapper::AssociationProtectedError)
|
|
258
|
-
|
|
259
|
-
Chain.delete_all
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
it "should throw AssociationProtectedError even when @items have not been loaded yet (:protect)" do
|
|
263
|
-
class Chain
|
|
264
|
-
has_and_belongs_to_many :chains, :dependent => :protect
|
|
265
|
-
end
|
|
266
|
-
Chain.auto_migrate!
|
|
267
|
-
|
|
268
|
-
chain = Chain.create(:name => "1")
|
|
269
|
-
chain.chains << Chain.create(:name => "2")
|
|
270
|
-
chain.chains << Chain.create(:name => "3")
|
|
271
|
-
chain.chains << Chain.create(:name => "4")
|
|
272
|
-
chain.save
|
|
273
|
-
chain4 = Chain.create(:name => "5")
|
|
274
|
-
chain.chains.first.chains << chain4
|
|
275
|
-
chain.chains.first.save
|
|
276
|
-
chain = Chain[chain.key]
|
|
277
|
-
|
|
278
|
-
lambda { chain.destroy! }.should raise_error(DataMapper::AssociationProtectedError)
|
|
279
|
-
|
|
280
|
-
Chain.delete_all
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
it "should correctly handle dependent associations (:nullify)" do
|
|
284
|
-
class Chain
|
|
285
|
-
has_and_belongs_to_many :chains, :dependent => :nullify
|
|
286
|
-
end
|
|
287
|
-
Chain.auto_migrate!
|
|
288
|
-
|
|
289
|
-
chain = Chain.create(:name => "1")
|
|
290
|
-
chain.chains << Chain.create(:name => "2")
|
|
291
|
-
chain.chains << Chain.create(:name => "3")
|
|
292
|
-
chain.chains << Chain.create(:name => "4")
|
|
293
|
-
chain.save
|
|
294
|
-
chain4 = Chain.create(:name => "5")
|
|
295
|
-
chain.chains.first.chains << chain4
|
|
296
|
-
chain.chains.first.save
|
|
297
|
-
chain = Chain[chain.key]
|
|
298
|
-
|
|
299
|
-
chain.destroy!
|
|
300
|
-
Chain.first(:name => "2").should_not be_nil
|
|
301
|
-
Chain.first(:name => "3").should_not be_nil
|
|
302
|
-
Chain.first(:name => "4").should_not be_nil
|
|
303
|
-
|
|
304
|
-
Chain.delete_all
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
describe DataMapper::Associations::HasAndBelongsToManyAssociation, "self-referential relationship" do
|
|
310
|
-
|
|
311
|
-
before(:all) do
|
|
312
|
-
fixtures(:tasks)
|
|
313
|
-
end
|
|
314
|
-
|
|
315
|
-
before(:each) do
|
|
316
|
-
@task_relax = Task.first(:name => "task_relax")
|
|
317
|
-
end
|
|
318
|
-
|
|
319
|
-
it "should allow a self-referential habtm by creating a related_* column for the right foreign key" do
|
|
320
|
-
tasks_assocation = database(:mock).schema[Task].associations.find { |a| a.name == :tasks }
|
|
321
|
-
|
|
322
|
-
tasks_assocation.right_foreign_key.name.should == :related_task_id
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
it "should load the self-referential association" do
|
|
326
|
-
database do
|
|
327
|
-
task_relax = Task.first(:name => "task_relax")
|
|
328
|
-
task_relax.tasks.size.should == 1
|
|
329
|
-
task_relax.tasks.first.should == Task.first(:name => "task_drink_heartily")
|
|
330
|
-
end
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
it "should allow a mirrored relationship between two rows (no infinite recursion)" do
|
|
334
|
-
task_vacation = Task.first(:name => "task_vacation")
|
|
335
|
-
|
|
336
|
-
@task_relax.tasks << task_vacation
|
|
337
|
-
@task_relax.save
|
|
338
|
-
|
|
339
|
-
task_vacation.tasks << @task_relax
|
|
340
|
-
task_vacation.save
|
|
341
|
-
|
|
342
|
-
@task_relax.reload!
|
|
343
|
-
@task_relax.tasks.should include(task_vacation)
|
|
344
|
-
|
|
345
|
-
task_vacation.reload!
|
|
346
|
-
task_vacation.tasks.should include(@task_relax)
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
describe DataMapper::Associations::HasAndBelongsToManyAssociation, "compatibility with belongs_to" do
|
|
352
|
-
|
|
353
|
-
it "should be able to save a job without interferring with applications" do
|
|
354
|
-
programmer = Job.create(:name => 'Programmer')
|
|
355
|
-
manager = Job.create(:name => 'Manager')
|
|
356
|
-
|
|
357
|
-
bob = Candidate.create(:name => 'Bob')
|
|
358
|
-
|
|
359
|
-
bob.applications << programmer << manager
|
|
360
|
-
|
|
361
|
-
bob.applications.should have(2).entries
|
|
362
|
-
bob.job.should be_nil
|
|
363
|
-
|
|
364
|
-
bob.job = programmer
|
|
365
|
-
|
|
366
|
-
bob.should be_dirty
|
|
367
|
-
bob.applications.should be_dirty
|
|
368
|
-
bob.job.should_not be_dirty # Because no property is changed on the has_many side.
|
|
369
|
-
|
|
370
|
-
bob.save!.should == true
|
|
371
|
-
|
|
372
|
-
impostor = Candidate[bob.id]
|
|
373
|
-
|
|
374
|
-
impostor.applications.should have(2).entries
|
|
375
|
-
impostor.job.should == programmer
|
|
376
|
-
end
|
|
377
|
-
end
|
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + "/../spec_helper"
|
|
2
|
-
|
|
3
|
-
describe DataMapper::Associations::HasManyAssociation do
|
|
4
|
-
|
|
5
|
-
before(:all) do
|
|
6
|
-
fixtures(:zoos)
|
|
7
|
-
fixtures(:exhibits)
|
|
8
|
-
fixtures(:fruit)
|
|
9
|
-
fixtures(:animals)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
after(:all) do
|
|
13
|
-
fixtures(:fruit)
|
|
14
|
-
fixtures(:animals)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
before(:each) do
|
|
18
|
-
@zoo = Zoo.new(:name => "ZOO")
|
|
19
|
-
@zoo.save
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
after(:each) do
|
|
23
|
-
@zoo.destroy!
|
|
24
|
-
Chain.delete_all
|
|
25
|
-
Fence.delete_all
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it "should provide a shallow_append method that doesn't impact the complementary association" do
|
|
29
|
-
project = Project.new
|
|
30
|
-
section = Section.new
|
|
31
|
-
project.sections.shallow_append(section)
|
|
32
|
-
section.project.should be_nil
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "assignment should not force associated items to load" do
|
|
36
|
-
dallas = Zoo.first(:name => 'Dallas')
|
|
37
|
-
Exhibit.new(:name => 'Weasel World!', :zoo => dallas)
|
|
38
|
-
dallas.exhibits.instance_variable_get('@items').should be_nil
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it "should use << for assignment" do
|
|
42
|
-
bob_land = Zoo.new(:name => 'Bob Land!')
|
|
43
|
-
bob_land.exhibits << Exhibit.new(:name => 'Cow')
|
|
44
|
-
bob_land.exhibits.should have(1).entries
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
it "should return an empty Enumerable for new objects" do
|
|
48
|
-
project = Project.new
|
|
49
|
-
project.sections.should be_a_kind_of(Enumerable)
|
|
50
|
-
project.sections.should be_empty
|
|
51
|
-
project.sections.should be_nil
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "should display correctly when inspected" do
|
|
55
|
-
Zoo.first(:name => 'Dallas').exhibits.inspect.should match(/\#\<Exhibit\:0x.{7}/)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it 'should lazily-load the association when Enumerable methods are called' do
|
|
59
|
-
database do |db|
|
|
60
|
-
san_diego = Zoo.first(:name => 'San Diego')
|
|
61
|
-
san_diego.exhibits.size.should == 2
|
|
62
|
-
san_diego.exhibits.should include(Exhibit.first(:name => 'Monkey Mayhem'))
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it 'should eager-load associations for an entire set' do
|
|
67
|
-
database do
|
|
68
|
-
zoos = Zoo.all
|
|
69
|
-
zoos.each do |zoo|
|
|
70
|
-
zoo.exhibits.each do |exhibit|
|
|
71
|
-
exhibit.zoo.should == zoo
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it "should be dirty even when clean objects are associated" do
|
|
78
|
-
zoo = Zoo.first(:name => 'New York')
|
|
79
|
-
zoo.exhibits << Exhibit.first
|
|
80
|
-
zoo.should be_dirty
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it "should proxy associations on the associated type" do
|
|
84
|
-
Zoo.first(:name => 'Miami').exhibits.animals.size.should == 1
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
it "should have a valid zoo setup for testing" do
|
|
88
|
-
@zoo.should be_valid
|
|
89
|
-
@zoo.should_not be_a_new_record
|
|
90
|
-
@zoo.id.should_not be_nil
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
it "should generate the SQL for a join statement" do
|
|
94
|
-
exhibits_association = database(:mock).schema[Zoo].associations.find { |a| a.name == :exhibits }
|
|
95
|
-
|
|
96
|
-
exhibits_association.to_sql.should == <<-EOS.compress_lines
|
|
97
|
-
JOIN `exhibits` ON `exhibits`.`zoo_id` = `zoos`.`id`
|
|
98
|
-
EOS
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it "should add an item to an association" do
|
|
102
|
-
bear = Exhibit.new( :name => "Bear")
|
|
103
|
-
@zoo.exhibits << bear
|
|
104
|
-
@zoo.exhibits.should include(bear)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it "should build a new item" do
|
|
108
|
-
bear = @zoo.exhibits.build( :name => "Bear" )
|
|
109
|
-
bear.should be_kind_of(Exhibit)
|
|
110
|
-
@zoo.exhibits.should include(bear)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
it "should not save the item when building" do
|
|
114
|
-
bear = @zoo.exhibits.build( :name => "Bear" )
|
|
115
|
-
bear.should be_new_record
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
it "should create a new item" do
|
|
119
|
-
bear = @zoo.exhibits.create( :name => "Bear" )
|
|
120
|
-
bear.should be_kind_of(Exhibit)
|
|
121
|
-
@zoo.exhibits.should include(bear)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
it "should save the item when creating" do
|
|
125
|
-
bear = @zoo.exhibits.create( :name => "Bear" )
|
|
126
|
-
bear.should_not be_new_record
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
it "should set the association to a saved target when added with <<" do
|
|
130
|
-
pirahna = Exhibit.new(:name => "Pirahna")
|
|
131
|
-
pirahna.zoo_id.should be_nil
|
|
132
|
-
|
|
133
|
-
@zoo.exhibits << pirahna
|
|
134
|
-
pirahna.zoo.should == @zoo
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it "should set the association to a non-saved target when added with <<" do
|
|
138
|
-
zoo = Zoo.new(:name => "My Zoo")
|
|
139
|
-
kangaroo = Exhibit.new(:name => "Kangaroo")
|
|
140
|
-
zoo.exhibits << kangaroo
|
|
141
|
-
kangaroo.zoo.should == zoo
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
it "should set the id of the exhibit when the associated zoo is saved" do
|
|
145
|
-
snake = Exhibit.new(:name => "Snake")
|
|
146
|
-
@zoo.exhibits << snake
|
|
147
|
-
@zoo.save
|
|
148
|
-
@zoo.id.should == snake.zoo_id
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
it "should update the foreign_key of already saved exhibits with a new zoo on zoo creation" do
|
|
152
|
-
zoo = Zoo.new(:name => "My Zoo")
|
|
153
|
-
snake = Exhibit.create(:name => "Snake")
|
|
154
|
-
tiger = Exhibit.create(:name => "Tiger")
|
|
155
|
-
zoo.exhibits << snake << tiger
|
|
156
|
-
zoo.save
|
|
157
|
-
snake.zoo_id.should == zoo.key
|
|
158
|
-
tiger.zoo_id.should == zoo.key
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
it "should set the id of an already saved exibit if it's added to a different zoo" do
|
|
162
|
-
beaver = Exhibit.new(:name => "Beaver")
|
|
163
|
-
beaver.save
|
|
164
|
-
beaver.should_not be_a_new_record
|
|
165
|
-
@zoo.exhibits << beaver
|
|
166
|
-
@zoo.save
|
|
167
|
-
beaver.zoo.should == @zoo
|
|
168
|
-
beaver.zoo_id.should == @zoo.id
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
it "should set the size of the assocation" do
|
|
172
|
-
@zoo.exhibits << Exhibit.new(:name => "anonymous")
|
|
173
|
-
@zoo.exhibits.size.should == 1
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
it "should give the association when an inspect is done on it" do
|
|
177
|
-
whale = Exhibit.new(:name => "Whale")
|
|
178
|
-
@zoo.exhibits << whale
|
|
179
|
-
@zoo.exhibits.should_not == "nil"
|
|
180
|
-
@zoo.exhibits.inspect.should_not be_nil
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
it "should generate the SQL for a join statement" do
|
|
184
|
-
fruit_association = database(:mock).schema[Animal].associations.find { |a| a.name == :favourite_fruit }
|
|
185
|
-
|
|
186
|
-
fruit_association.to_sql.should == <<-EOS.compress_lines
|
|
187
|
-
JOIN `fruit` ON `fruit`.`devourer_id` = `animals`.`id`
|
|
188
|
-
EOS
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
it "is assigned a devourer_id" do
|
|
192
|
-
bob = Animal.new(:name => 'bob')
|
|
193
|
-
fruit = Fruit.first
|
|
194
|
-
bob.favourite_fruit = fruit
|
|
195
|
-
|
|
196
|
-
bob.save
|
|
197
|
-
|
|
198
|
-
bob.reload!
|
|
199
|
-
fruit.devourer_id.should eql(bob.id)
|
|
200
|
-
bob.favourite_fruit.should == fruit
|
|
201
|
-
|
|
202
|
-
fruit.reload!
|
|
203
|
-
fruit.devourer_of_souls.should == bob
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
it "Should handle setting complementary associations" do
|
|
207
|
-
# pending "http://wm.lighthouseapp.com/projects/4819/tickets/84-belongs_to-associations-not-working-for-me"
|
|
208
|
-
u1 = User.create(:name => "u1", :email => "test@email.com")
|
|
209
|
-
u1.comments.should be_empty
|
|
210
|
-
|
|
211
|
-
c1 = Comment.create(:comment => "c", :author => u1)
|
|
212
|
-
|
|
213
|
-
u1.comments.should_not be_empty
|
|
214
|
-
u1.comments.should include(c1)
|
|
215
|
-
|
|
216
|
-
u1.reload!
|
|
217
|
-
u1.comments.should_not be_empty
|
|
218
|
-
u1.comments.should include(c1)
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
it "should allow updates to associations using association_keys=" do
|
|
222
|
-
# pending "http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/109-associations-should-support-association_keys-methods"
|
|
223
|
-
database(:default) do
|
|
224
|
-
london = Zoo.create(:name => "London")
|
|
225
|
-
dunes = Exhibit.create(:name => "Dunes")
|
|
226
|
-
|
|
227
|
-
london.exhibits.should be_empty
|
|
228
|
-
london.send(:exhibits_keys=, dunes.key)
|
|
229
|
-
london.save!.should be_true
|
|
230
|
-
|
|
231
|
-
london.should have(1).exhibits
|
|
232
|
-
london.exhibits.should include(dunes)
|
|
233
|
-
|
|
234
|
-
london.reload!
|
|
235
|
-
london.should have(1).exhibits
|
|
236
|
-
|
|
237
|
-
london.destroy!
|
|
238
|
-
dunes.destroy!
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
it "should correctly handle dependent associations (:destroy)" do
|
|
243
|
-
class Fence
|
|
244
|
-
has_many :chains, :dependent => :destroy
|
|
245
|
-
end
|
|
246
|
-
#Chain.should_receive(:destroy!).and_return(true)
|
|
247
|
-
|
|
248
|
-
fence = Fence.create(:name => "Great Wall of China")
|
|
249
|
-
fence.chains << Chain.create(:name => "1")
|
|
250
|
-
fence.chains << Chain.create(:name => "2")
|
|
251
|
-
fence.chains << Chain.create(:name => "3")
|
|
252
|
-
fence.save
|
|
253
|
-
chain = Chain.create(:name => "4")
|
|
254
|
-
fence = Fence[fence.key]
|
|
255
|
-
|
|
256
|
-
fence.destroy!
|
|
257
|
-
Chain.first(:name => "1").should be_nil
|
|
258
|
-
Chain.first(:name => "2").should be_nil
|
|
259
|
-
Chain.first(:name => "3").should be_nil
|
|
260
|
-
Chain.first(:name => "4").should_not be_nil
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
it "should correctly handle dependent associations (:delete)" do
|
|
264
|
-
class Fence
|
|
265
|
-
has_many :chains, :dependent => :delete
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
fence = Fence.create(:name => "Great Wall of China")
|
|
269
|
-
fence.chains << Chain.create(:name => "1")
|
|
270
|
-
fence.chains << Chain.create(:name => "2")
|
|
271
|
-
fence.chains << Chain.create(:name => "3")
|
|
272
|
-
fence.save
|
|
273
|
-
chain = Chain.create(:name => "4")
|
|
274
|
-
fence = Fence[fence.key]
|
|
275
|
-
|
|
276
|
-
fence.destroy!
|
|
277
|
-
Chain.first(:name => "1").should be_nil
|
|
278
|
-
Chain.first(:name => "2").should be_nil
|
|
279
|
-
Chain.first(:name => "3").should be_nil
|
|
280
|
-
Chain.first(:name => "4").should_not be_nil
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
it "should correctly handle dependent associations (:protect)" do
|
|
284
|
-
class Fence
|
|
285
|
-
has_many :chains, :dependent => :protect
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
fence = Fence.create(:name => "Great Wall of China")
|
|
289
|
-
fence.chains << Chain.create(:name => "1")
|
|
290
|
-
fence.chains << Chain.create(:name => "2")
|
|
291
|
-
fence.chains << Chain.create(:name => "3")
|
|
292
|
-
fence.save
|
|
293
|
-
chain = Chain.create(:name => "4")
|
|
294
|
-
fence = Fence[fence.key]
|
|
295
|
-
|
|
296
|
-
lambda { fence.destroy! }.should raise_error(DataMapper::AssociationProtectedError)
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
it "should throw AssociationProtectedError even when @items have not been loaded yet (:protect)" do
|
|
300
|
-
class Fence
|
|
301
|
-
has_many :chains, :dependent => :protect
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
fence = Fence.create(:name => "Great Wall of China")
|
|
305
|
-
fence.chains << Chain.create(:name => "1")
|
|
306
|
-
fence.chains << Chain.create(:name => "2")
|
|
307
|
-
fence.chains << Chain.create(:name => "3")
|
|
308
|
-
fence.save
|
|
309
|
-
chain = Chain.create(:name => "4")
|
|
310
|
-
fence = Fence[fence.key]
|
|
311
|
-
|
|
312
|
-
lambda { fence.destroy! }.should raise_error(DataMapper::AssociationProtectedError)
|
|
313
|
-
end
|
|
314
|
-
|
|
315
|
-
it "should correctly handle dependent associations (:nullify)" do
|
|
316
|
-
class Fence
|
|
317
|
-
has_many :chains, :dependent => :nullify
|
|
318
|
-
end
|
|
319
|
-
|
|
320
|
-
fence = Fence.create(:name => "Great Wall of China")
|
|
321
|
-
fence.chains << Chain.create(:name => "1")
|
|
322
|
-
fence.chains << Chain.create(:name => "2")
|
|
323
|
-
fence.chains << Chain.create(:name => "3")
|
|
324
|
-
fence.save
|
|
325
|
-
chain = Chain.create(:name => "4")
|
|
326
|
-
fence = Fence[fence.key]
|
|
327
|
-
|
|
328
|
-
fence.destroy!
|
|
329
|
-
Chain.first(:name => "1").should_not be_nil
|
|
330
|
-
Chain.first(:name => "1").fence_id.should be_nil
|
|
331
|
-
Chain.first(:name => "2").should_not be_nil
|
|
332
|
-
Chain.first(:name => "2").fence_id.should be_nil
|
|
333
|
-
Chain.first(:name => "3").should_not be_nil
|
|
334
|
-
Chain.first(:name => "3").fence_id.should be_nil
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
end
|