sequel 4.7.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +46 -0
- data/README.rdoc +25 -1
- data/doc/active_record.rdoc +1 -1
- data/doc/advanced_associations.rdoc +143 -17
- data/doc/association_basics.rdoc +80 -59
- data/doc/release_notes/4.8.0.txt +175 -0
- data/lib/sequel/adapters/odbc.rb +1 -1
- data/lib/sequel/adapters/odbc/mssql.rb +4 -2
- data/lib/sequel/adapters/shared/postgres.rb +19 -3
- data/lib/sequel/adapters/shared/sqlite.rb +3 -3
- data/lib/sequel/ast_transformer.rb +1 -1
- data/lib/sequel/dataset/actions.rb +1 -1
- data/lib/sequel/dataset/graph.rb +23 -9
- data/lib/sequel/dataset/misc.rb +2 -2
- data/lib/sequel/dataset/sql.rb +3 -3
- data/lib/sequel/extensions/columns_introspection.rb +1 -1
- data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +1 -1
- data/lib/sequel/extensions/pg_array_ops.rb +6 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +7 -0
- data/lib/sequel/extensions/pg_json_ops.rb +5 -0
- data/lib/sequel/extensions/query.rb +8 -2
- data/lib/sequel/extensions/to_dot.rb +1 -1
- data/lib/sequel/model/associations.rb +476 -152
- data/lib/sequel/plugins/class_table_inheritance.rb +11 -3
- data/lib/sequel/plugins/dataset_associations.rb +21 -18
- data/lib/sequel/plugins/many_through_many.rb +87 -20
- data/lib/sequel/plugins/nested_attributes.rb +12 -0
- data/lib/sequel/plugins/pg_array_associations.rb +31 -12
- data/lib/sequel/plugins/single_table_inheritance.rb +9 -1
- data/lib/sequel/sql.rb +1 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +2 -2
- data/spec/adapters/postgres_spec.rb +7 -0
- data/spec/core/object_graph_spec.rb +250 -196
- data/spec/extensions/core_refinements_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +100 -6
- data/spec/extensions/many_through_many_spec.rb +1002 -19
- data/spec/extensions/nested_attributes_spec.rb +24 -0
- data/spec/extensions/pg_array_associations_spec.rb +17 -12
- data/spec/extensions/pg_array_spec.rb +4 -2
- data/spec/extensions/spec_helper.rb +1 -1
- data/spec/integration/associations_test.rb +1003 -48
- data/spec/integration/dataset_test.rb +12 -5
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/type_test.rb +1 -1
- data/spec/model/associations_spec.rb +467 -130
- data/spec/model/eager_loading_spec.rb +332 -5
- metadata +5 -3
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
2
|
|
3
|
-
if RUBY_VERSION >= '2.0.0' &&
|
3
|
+
if RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby'
|
4
4
|
Sequel.extension :core_refinements, :pg_array, :pg_hstore, :pg_row, :pg_range, :pg_row_ops, :pg_range_ops, :pg_array_ops, :pg_hstore_ops, :pg_json, :pg_json_ops
|
5
5
|
using Sequel::CoreRefinements
|
6
6
|
|
@@ -3,6 +3,10 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
3
3
|
describe "Sequel::Plugins::DatasetAssociations" do
|
4
4
|
before do
|
5
5
|
@db = Sequel.mock
|
6
|
+
@db.extend_datasets do
|
7
|
+
def supports_window_functions?; true; end
|
8
|
+
def supports_distinct_on?; true; end
|
9
|
+
end
|
6
10
|
@Base = Class.new(Sequel::Model)
|
7
11
|
@Base.plugin :dataset_associations
|
8
12
|
|
@@ -29,10 +33,12 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
29
33
|
@Artist.one_to_one :first_album, :class=>@Album
|
30
34
|
@Album.many_to_one :artist, :class=>@Artist
|
31
35
|
@Album.many_to_many :tags, :class=>@Tag
|
36
|
+
@Album.one_through_one :first_tag, :class=>@Tag, :right_key=>:tag_id
|
32
37
|
@Tag.many_to_many :albums, :class=>@Album
|
33
38
|
@Artist.pg_array_to_many :artist_tags, :class=>@Tag, :key=>:tag_ids
|
34
39
|
@Tag.many_to_pg_array :artists, :class=>@Artist
|
35
40
|
@Artist.many_through_many :tags, [[:albums, :artist_id, :id], [:albums_tags, :album_id, :tag_id]], :class=>@Tag
|
41
|
+
@Artist.one_through_many :otag, [[:albums, :artist_id, :id], [:albums_tags, :album_id, :tag_id]], :class=>@Tag
|
36
42
|
end
|
37
43
|
|
38
44
|
it "should work for many_to_one associations" do
|
@@ -60,14 +66,28 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
60
66
|
ds = @Album.tags
|
61
67
|
ds.should be_a_kind_of(Sequel::Dataset)
|
62
68
|
ds.model.should == @Tag
|
63
|
-
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM
|
69
|
+
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) WHERE ((albums_tags.album_id) IN (SELECT albums.id FROM albums))))"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should work for one_through_one associations" do
|
73
|
+
ds = @Album.first_tags
|
74
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
75
|
+
ds.model.should == @Tag
|
76
|
+
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) WHERE ((albums_tags.album_id) IN (SELECT albums.id FROM albums))))"
|
64
77
|
end
|
65
78
|
|
66
79
|
it "should work for many_through_many associations" do
|
67
80
|
ds = @Artist.tags
|
68
81
|
ds.should be_a_kind_of(Sequel::Dataset)
|
69
82
|
ds.model.should == @Tag
|
70
|
-
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM artists INNER JOIN albums ON (albums.artist_id = artists.id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id)))"
|
83
|
+
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM artists INNER JOIN albums ON (albums.artist_id = artists.id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags ON (tags.id = albums_tags.tag_id) WHERE (albums.artist_id IN (SELECT artists.id FROM artists))))"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should work for one_through_many associations" do
|
87
|
+
ds = @Artist.otags
|
88
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
89
|
+
ds.model.should == @Tag
|
90
|
+
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM artists INNER JOIN albums ON (albums.artist_id = artists.id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags ON (tags.id = albums_tags.tag_id) WHERE (albums.artist_id IN (SELECT artists.id FROM artists))))"
|
71
91
|
end
|
72
92
|
|
73
93
|
it "should work for pg_array_to_many associations" do
|
@@ -104,7 +124,7 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
104
124
|
ds = @Artist.albums.tags
|
105
125
|
ds.should be_a_kind_of(Sequel::Dataset)
|
106
126
|
ds.model.should == @Tag
|
107
|
-
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM
|
127
|
+
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) WHERE ((albums_tags.album_id) IN (SELECT albums.id FROM albums WHERE (albums.artist_id IN (SELECT artists.id FROM artists))))))"
|
108
128
|
end
|
109
129
|
|
110
130
|
it "should deal correctly with filters before the association method" do
|
@@ -154,11 +174,45 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
154
174
|
@Artist.one_to_many :albums, :clone=>:albums, :select=>[:id, :name]
|
155
175
|
@Artist.albums.sql.should == "SELECT id, name FROM albums WHERE (albums.artist_id IN (SELECT artists.id FROM artists))"
|
156
176
|
end
|
177
|
+
|
178
|
+
it "should deal correctly with :order option for one_to_one associations" do
|
179
|
+
@Artist.one_to_one :first_album, :clone=>:first_album, :order=>:name
|
180
|
+
@Artist.first_albums.sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id IN (SELECT artists.id FROM artists)) AND (albums.id IN (SELECT DISTINCT ON (albums.artist_id) albums.id FROM albums ORDER BY albums.artist_id, name))) ORDER BY name'
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should deal correctly with :limit option for one_to_many associations" do
|
184
|
+
@Artist.one_to_many :albums, :clone=>:albums, :limit=>10, :order=>:name
|
185
|
+
@Artist.albums.sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id IN (SELECT artists.id FROM artists)) AND (albums.id IN (SELECT id FROM (SELECT albums.id, row_number() OVER (PARTITION BY albums.artist_id ORDER BY name) AS x_sequel_row_number_x FROM albums) AS t1 WHERE (x_sequel_row_number_x <= 10)))) ORDER BY name'
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should deal correctly with :order option for one_through_one associations" do
|
189
|
+
@Album.one_through_one :first_tag, :clone=>:first_tag, :order=>:tags__name
|
190
|
+
@Album.first_tags.sql.should == 'SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) WHERE (((albums_tags.album_id) IN (SELECT albums.id FROM albums)) AND ((albums_tags.album_id, tags.id) IN (SELECT DISTINCT ON (albums_tags.album_id) albums_tags.album_id, tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) ORDER BY albums_tags.album_id, tags.name))))) ORDER BY tags.name'
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should deal correctly with :limit option for many_to_many associations" do
|
194
|
+
@Album.many_to_many :tags, :clone=>:tags, :limit=>10, :order=>:tags__name
|
195
|
+
@Album.tags.sql.should == 'SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) WHERE (((albums_tags.album_id) IN (SELECT albums.id FROM albums)) AND ((albums_tags.album_id, tags.id) IN (SELECT b, c FROM (SELECT albums_tags.album_id AS b, tags.id AS c, row_number() OVER (PARTITION BY albums_tags.album_id ORDER BY tags.name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id)) AS t1 WHERE (x_sequel_row_number_x <= 10)))))) ORDER BY tags.name'
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should deal correctly with :order option for one_through_many associations" do
|
199
|
+
@Artist.one_through_many :otag, :clone=>:otag, :order=>:id, :order=>:tags__name
|
200
|
+
@Artist.otags.sql.should == 'SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM artists INNER JOIN albums ON (albums.artist_id = artists.id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags ON (tags.id = albums_tags.tag_id) WHERE ((albums.artist_id IN (SELECT artists.id FROM artists)) AND ((albums.artist_id, tags.id) IN (SELECT DISTINCT ON (albums.artist_id) albums.artist_id, tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) ORDER BY albums.artist_id, tags.name))))) ORDER BY tags.name'
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should deal correctly with :limit option for many_through_many associations" do
|
204
|
+
@Artist.many_through_many :tags, :clone=>:tags, :limit=>10, :order=>:tags__name
|
205
|
+
@Artist.tags.sql.should == 'SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM artists INNER JOIN albums ON (albums.artist_id = artists.id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags ON (tags.id = albums_tags.tag_id) WHERE ((albums.artist_id IN (SELECT artists.id FROM artists)) AND ((albums.artist_id, tags.id) IN (SELECT b, c FROM (SELECT albums.artist_id AS b, tags.id AS c, row_number() OVER (PARTITION BY albums.artist_id ORDER BY tags.name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id)) AS t1 WHERE (x_sequel_row_number_x <= 10)))))) ORDER BY tags.name'
|
206
|
+
end
|
157
207
|
end
|
158
208
|
|
159
209
|
describe "Sequel::Plugins::DatasetAssociations with composite keys" do
|
160
210
|
before do
|
161
211
|
@db = Sequel.mock
|
212
|
+
@db.extend_datasets do
|
213
|
+
def supports_window_functions?; true; end
|
214
|
+
def supports_distinct_on?; true; end
|
215
|
+
end
|
162
216
|
@Base = Class.new(Sequel::Model)
|
163
217
|
@Base.plugin :dataset_associations
|
164
218
|
|
@@ -187,8 +241,10 @@ describe "Sequel::Plugins::DatasetAssociations with composite keys" do
|
|
187
241
|
@Artist.one_to_one :first_album, :class=>@Album, :key=>[:artist_id1, :artist_id2]
|
188
242
|
@Album.many_to_one :artist, :class=>@Artist, :key=>[:artist_id1, :artist_id2]
|
189
243
|
@Album.many_to_many :tags, :class=>@Tag, :left_key=>[:album_id1, :album_id2], :right_key=>[:tag_id1, :tag_id2]
|
244
|
+
@Album.one_through_one :first_tag, :class=>@Tag, :left_key=>[:album_id1, :album_id2], :right_key=>[:tag_id1, :tag_id2]
|
190
245
|
@Tag.many_to_many :albums, :class=>@Album, :right_key=>[:album_id1, :album_id2], :left_key=>[:tag_id1, :tag_id2]
|
191
246
|
@Artist.many_through_many :tags, [[:albums, [:artist_id1, :artist_id2], [:id1, :id2]], [:albums_tags, [:album_id1, :album_id2], [:tag_id1, :tag_id2]]], :class=>@Tag
|
247
|
+
@Artist.one_through_many :otag, [[:albums, [:artist_id1, :artist_id2], [:id1, :id2]], [:albums_tags, [:album_id1, :album_id2], [:tag_id1, :tag_id2]]], :class=>@Tag
|
192
248
|
end
|
193
249
|
|
194
250
|
it "should work for many_to_one associations" do
|
@@ -204,14 +260,52 @@ describe "Sequel::Plugins::DatasetAssociations with composite keys" do
|
|
204
260
|
end
|
205
261
|
|
206
262
|
it "should work for many_to_many associations" do
|
207
|
-
@Album.tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM
|
263
|
+
@Album.tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id1 = tags.id1) AND (albums_tags.tag_id2 = tags.id2)) WHERE ((albums_tags.album_id1, albums_tags.album_id2) IN (SELECT albums.id1, albums.id2 FROM albums))))"
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should work for one_through_one associations" do
|
267
|
+
@Album.first_tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id1 = tags.id1) AND (albums_tags.tag_id2 = tags.id2)) WHERE ((albums_tags.album_id1, albums_tags.album_id2) IN (SELECT albums.id1, albums.id2 FROM albums))))"
|
208
268
|
end
|
209
269
|
|
210
270
|
it "should work for many_through_many associations" do
|
211
|
-
@Artist.tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM artists INNER JOIN albums ON ((albums.artist_id1 = artists.id1) AND (albums.artist_id2 = artists.id2)) INNER JOIN albums_tags ON ((albums_tags.album_id1 = albums.id1) AND (albums_tags.album_id2 = albums.id2))))"
|
271
|
+
@Artist.tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM artists INNER JOIN albums ON ((albums.artist_id1 = artists.id1) AND (albums.artist_id2 = artists.id2)) INNER JOIN albums_tags ON ((albums_tags.album_id1 = albums.id1) AND (albums_tags.album_id2 = albums.id2)) INNER JOIN tags ON ((tags.id1 = albums_tags.tag_id1) AND (tags.id2 = albums_tags.tag_id2)) WHERE ((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists))))"
|
272
|
+
end
|
273
|
+
|
274
|
+
it "should work for one_through_many associations" do
|
275
|
+
@Artist.otags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM artists INNER JOIN albums ON ((albums.artist_id1 = artists.id1) AND (albums.artist_id2 = artists.id2)) INNER JOIN albums_tags ON ((albums_tags.album_id1 = albums.id1) AND (albums_tags.album_id2 = albums.id2)) INNER JOIN tags ON ((tags.id1 = albums_tags.tag_id1) AND (tags.id2 = albums_tags.tag_id2)) WHERE ((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists))))"
|
212
276
|
end
|
213
277
|
|
214
278
|
it "should work correctly when chaining" do
|
215
|
-
@Artist.albums.tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM
|
279
|
+
@Artist.albums.tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id1 = tags.id1) AND (albums_tags.tag_id2 = tags.id2)) WHERE ((albums_tags.album_id1, albums_tags.album_id2) IN (SELECT albums.id1, albums.id2 FROM albums WHERE ((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists))))))"
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should deal correctly with :order option for one_to_one associations" do
|
283
|
+
@Artist.one_to_one :first_album, :clone=>:first_album, :order=>:name
|
284
|
+
@Artist.first_albums.sql.should == 'SELECT * FROM albums WHERE (((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists)) AND ((albums.id1, albums.id2) IN (SELECT DISTINCT ON (albums.artist_id1, albums.artist_id2) albums.id1, albums.id2 FROM albums ORDER BY albums.artist_id1, albums.artist_id2, name))) ORDER BY name'
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should deal correctly with :limit option for one_to_many associations" do
|
288
|
+
@Artist.one_to_many :albums, :clone=>:albums, :limit=>10, :order=>:name
|
289
|
+
@Artist.albums.sql.should == 'SELECT * FROM albums WHERE (((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists)) AND ((albums.id1, albums.id2) IN (SELECT id1, id2 FROM (SELECT albums.id1, albums.id2, row_number() OVER (PARTITION BY albums.artist_id1, albums.artist_id2 ORDER BY name) AS x_sequel_row_number_x FROM albums) AS t1 WHERE (x_sequel_row_number_x <= 10)))) ORDER BY name'
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should deal correctly with :order option for one_through_one associations" do
|
293
|
+
@Album.one_through_one :first_tag, :clone=>:first_tag, :order=>:tags__name
|
294
|
+
@Album.first_tags.sql.should == 'SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id1 = tags.id1) AND (albums_tags.tag_id2 = tags.id2)) WHERE (((albums_tags.album_id1, albums_tags.album_id2) IN (SELECT albums.id1, albums.id2 FROM albums)) AND ((albums_tags.album_id1, albums_tags.album_id2, tags.id1, tags.id2) IN (SELECT DISTINCT ON (albums_tags.album_id1, albums_tags.album_id2) albums_tags.album_id1, albums_tags.album_id2, tags.id1, tags.id2 FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id1 = tags.id1) AND (albums_tags.tag_id2 = tags.id2)) ORDER BY albums_tags.album_id1, albums_tags.album_id2, tags.name))))) ORDER BY tags.name'
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should deal correctly with :limit option for many_to_many associations" do
|
298
|
+
@Album.many_to_many :tags, :clone=>:tags, :limit=>10, :order=>:tags__name
|
299
|
+
@Album.tags.sql.should == 'SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id1 = tags.id1) AND (albums_tags.tag_id2 = tags.id2)) WHERE (((albums_tags.album_id1, albums_tags.album_id2) IN (SELECT albums.id1, albums.id2 FROM albums)) AND ((albums_tags.album_id1, albums_tags.album_id2, tags.id1, tags.id2) IN (SELECT b, c, d, e FROM (SELECT albums_tags.album_id1 AS b, albums_tags.album_id2 AS c, tags.id1 AS d, tags.id2 AS e, row_number() OVER (PARTITION BY albums_tags.album_id1, albums_tags.album_id2 ORDER BY tags.name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id1 = tags.id1) AND (albums_tags.tag_id2 = tags.id2))) AS t1 WHERE (x_sequel_row_number_x <= 10)))))) ORDER BY tags.name'
|
300
|
+
end
|
301
|
+
|
302
|
+
it "should deal correctly with :order option for one_through_many associations" do
|
303
|
+
@Artist.one_through_many :otag, :clone=>:otag, :order=>:tags__name
|
304
|
+
@Artist.otags.sql.should == 'SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM artists INNER JOIN albums ON ((albums.artist_id1 = artists.id1) AND (albums.artist_id2 = artists.id2)) INNER JOIN albums_tags ON ((albums_tags.album_id1 = albums.id1) AND (albums_tags.album_id2 = albums.id2)) INNER JOIN tags ON ((tags.id1 = albums_tags.tag_id1) AND (tags.id2 = albums_tags.tag_id2)) WHERE (((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists)) AND ((albums.artist_id1, albums.artist_id2, tags.id1, tags.id2) IN (SELECT DISTINCT ON (albums.artist_id1, albums.artist_id2) albums.artist_id1, albums.artist_id2, tags.id1, tags.id2 FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id1 = tags.id1) AND (albums_tags.tag_id2 = tags.id2)) INNER JOIN albums ON ((albums.id1 = albums_tags.album_id1) AND (albums.id2 = albums_tags.album_id2)) ORDER BY albums.artist_id1, albums.artist_id2, tags.name))))) ORDER BY tags.name'
|
305
|
+
end
|
306
|
+
|
307
|
+
it "should deal correctly with :limit option for many_through_many associations" do
|
308
|
+
@Artist.many_through_many :tags, :clone=>:tags, :limit=>10, :order=>:tags__name
|
309
|
+
@Artist.tags.sql.should == 'SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM artists INNER JOIN albums ON ((albums.artist_id1 = artists.id1) AND (albums.artist_id2 = artists.id2)) INNER JOIN albums_tags ON ((albums_tags.album_id1 = albums.id1) AND (albums_tags.album_id2 = albums.id2)) INNER JOIN tags ON ((tags.id1 = albums_tags.tag_id1) AND (tags.id2 = albums_tags.tag_id2)) WHERE (((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists)) AND ((albums.artist_id1, albums.artist_id2, tags.id1, tags.id2) IN (SELECT b, c, d, e FROM (SELECT albums.artist_id1 AS b, albums.artist_id2 AS c, tags.id1 AS d, tags.id2 AS e, row_number() OVER (PARTITION BY albums.artist_id1, albums.artist_id2 ORDER BY tags.name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id1 = tags.id1) AND (albums_tags.tag_id2 = tags.id2)) INNER JOIN albums ON ((albums.id1 = albums_tags.album_id1) AND (albums.id2 = albums_tags.album_id2))) AS t1 WHERE (x_sequel_row_number_x <= 10)))))) ORDER BY tags.name'
|
216
310
|
end
|
217
311
|
end
|
@@ -102,13 +102,16 @@ describe Sequel::Model, "many_through_many" do
|
|
102
102
|
end
|
103
103
|
|
104
104
|
it "should handle multiple aliasing of tables" do
|
105
|
-
|
105
|
+
begin
|
106
|
+
class ::Album < Sequel::Model
|
107
|
+
end
|
108
|
+
@c1.many_through_many :albums, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id], [:artists, :id, :id], [:albums_artists, :artist_id, :album_id]]
|
109
|
+
n = @c1.load(:id => 1234)
|
110
|
+
n.albums_dataset.sql.should == 'SELECT albums.* FROM albums INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) INNER JOIN artists ON (artists.id = albums_artists.artist_id) INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) INNER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) INNER JOIN albums_artists AS albums_artists_1 ON ((albums_artists_1.album_id = albums_0.id) AND (albums_artists_1.artist_id = 1234))'
|
111
|
+
n.albums.should == [Album.load(:id=>1, :x=>1)]
|
112
|
+
ensure
|
113
|
+
Object.send(:remove_const, :Album)
|
106
114
|
end
|
107
|
-
@c1.many_through_many :albums, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id], [:artists, :id, :id], [:albums_artists, :artist_id, :album_id]]
|
108
|
-
n = @c1.load(:id => 1234)
|
109
|
-
n.albums_dataset.sql.should == 'SELECT albums.* FROM albums INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) INNER JOIN artists ON (artists.id = albums_artists.artist_id) INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) INNER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) INNER JOIN albums_artists AS albums_artists_1 ON ((albums_artists_1.album_id = albums_0.id) AND (albums_artists_1.artist_id = 1234))'
|
110
|
-
n.albums.should == [Album.load(:id=>1, :x=>1)]
|
111
|
-
Object.send(:remove_const, :Album)
|
112
115
|
end
|
113
116
|
|
114
117
|
it "should use explicit class if given" do
|
@@ -156,17 +159,41 @@ describe Sequel::Model, "many_through_many" do
|
|
156
159
|
|
157
160
|
it "should allowing filtering by many_through_many associations with :conditions" do
|
158
161
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
159
|
-
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE (
|
162
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id = 1234))))"
|
160
163
|
end
|
161
164
|
|
162
165
|
it "should allowing filtering by many_through_many associations with :conditions with a single through table" do
|
163
166
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id]], :conditions=>{:name=>'A'}
|
164
|
-
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE (
|
167
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_artists ON (albums_artists.album_id = tags.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id = 1234))))"
|
165
168
|
end
|
166
169
|
|
167
170
|
it "should allowing filtering by many_through_many associations with :conditions and composite keys" do
|
168
171
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
169
|
-
@c1.filter(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == "SELECT * FROM artists WHERE ((
|
172
|
+
@c1.filter(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id = 1))))"
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should allowing filtering by many_through_many associations with :limit" do
|
176
|
+
def (@c2.dataset).supports_window_functions?; true end
|
177
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>10
|
178
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT b, c FROM (SELECT albums_artists.artist_id AS b, tags.id AS c, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id)) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1234))))'
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should allowing filtering by many_through_many associations with :limit and composite keys" do
|
182
|
+
def (@c2.dataset).supports_window_functions?; true end
|
183
|
+
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :limit=>10
|
184
|
+
@c1.filter(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT b, c, d FROM (SELECT albums_artists.b1 AS b, albums_artists.b2 AS c, tags.id AS d, row_number() OVER (PARTITION BY albums_artists.b1, albums_artists.b2) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2))) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1))))'
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should allowing filtering by many_through_many associations with :limit and :conditions" do
|
188
|
+
def (@c2.dataset).supports_window_functions?; true end
|
189
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}, :limit=>10
|
190
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT b, c FROM (SELECT albums_artists.artist_id AS b, tags.id AS c, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (name = 'A')) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1234))))"
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should allowing filtering by many_through_many associations with :limit and :conditions and composite keys" do
|
194
|
+
def (@c2.dataset).supports_window_functions?; true end
|
195
|
+
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}, :limit=>10
|
196
|
+
@c1.filter(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT b, c, d FROM (SELECT albums_artists.b1 AS b, albums_artists.b2 AS c, tags.id AS d, row_number() OVER (PARTITION BY albums_artists.b1, albums_artists.b2) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE (name = 'A')) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1))))"
|
170
197
|
end
|
171
198
|
|
172
199
|
it "should allowing excluding by many_through_many associations" do
|
@@ -181,12 +208,12 @@ describe Sequel::Model, "many_through_many" do
|
|
181
208
|
|
182
209
|
it "should allowing excluding by many_through_many associations with :conditions" do
|
183
210
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
184
|
-
@c1.exclude(:tags=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM
|
211
|
+
@c1.exclude(:tags=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id = 1234)))) OR (artists.id IS NULL))"
|
185
212
|
end
|
186
213
|
|
187
214
|
it "should allowing excluding by many_through_many associations with :conditions and composite keys" do
|
188
215
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
189
|
-
@c1.exclude(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == "SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM
|
216
|
+
@c1.exclude(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == "SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id = 1)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))"
|
190
217
|
end
|
191
218
|
|
192
219
|
it "should allowing filtering by multiple many_through_many associations" do
|
@@ -201,12 +228,12 @@ describe Sequel::Model, "many_through_many" do
|
|
201
228
|
|
202
229
|
it "should allowing filtering by multiple many_through_many associations with :conditions" do
|
203
230
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
204
|
-
@c1.filter(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == "SELECT * FROM artists WHERE (
|
231
|
+
@c1.filter(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id IN (1234, 2345)))))"
|
205
232
|
end
|
206
233
|
|
207
234
|
it "should allowing filtering by multiple many_through_many associations with :conditions and composite keys" do
|
208
235
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
209
|
-
@c1.filter(:tags=>[@c2.load(:id=>1, :h1=>1234, :h2=>85), @c2.load(:id=>2, :h1=>2345, :h2=>95)]).sql.should == "SELECT * FROM artists WHERE ((
|
236
|
+
@c1.filter(:tags=>[@c2.load(:id=>1, :h1=>1234, :h2=>85), @c2.load(:id=>2, :h1=>2345, :h2=>95)]).sql.should == "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id IN (1, 2)))))"
|
210
237
|
end
|
211
238
|
|
212
239
|
it "should allowing excluding by multiple many_through_many associations" do
|
@@ -221,12 +248,12 @@ describe Sequel::Model, "many_through_many" do
|
|
221
248
|
|
222
249
|
it "should allowing excluding by multiple many_through_many associations with :conditions" do
|
223
250
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
224
|
-
@c1.exclude(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == "SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM
|
251
|
+
@c1.exclude(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == "SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id IN (1234, 2345))))) OR (artists.id IS NULL))"
|
225
252
|
end
|
226
253
|
|
227
254
|
it "should allowing excluding by multiple many_through_many associations with :conditions and composite keys" do
|
228
255
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
229
|
-
@c1.exclude(:tags=>[@c2.load(:id=>1, :h1=>1234, :h2=>85), @c2.load(:id=>2, :h1=>2345, :h2=>95)]).sql.should == "SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM
|
256
|
+
@c1.exclude(:tags=>[@c2.load(:id=>1, :h1=>1234, :h2=>85), @c2.load(:id=>2, :h1=>2345, :h2=>95)]).sql.should == "SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id IN (1, 2))))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))"
|
230
257
|
end
|
231
258
|
|
232
259
|
it "should allowing filtering/excluding many_through_many associations with NULL values" do
|
@@ -247,12 +274,12 @@ describe Sequel::Model, "many_through_many" do
|
|
247
274
|
|
248
275
|
it "should allowing filtering by many_through_many association datasets with :conditions" do
|
249
276
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
250
|
-
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE (
|
277
|
+
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (x = 1))))))"
|
251
278
|
end
|
252
279
|
|
253
280
|
it "should allowing filtering by many_through_many association datasets with :conditions and composite keys" do
|
254
281
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
255
|
-
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE ((
|
282
|
+
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (x = 1))))))"
|
256
283
|
end
|
257
284
|
|
258
285
|
it "should allowing excluding by many_through_many association datasets" do
|
@@ -267,12 +294,12 @@ describe Sequel::Model, "many_through_many" do
|
|
267
294
|
|
268
295
|
it "should allowing excluding by many_through_many association datasets with :conditions" do
|
269
296
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
270
|
-
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM
|
297
|
+
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (x = 1)))))) OR (artists.id IS NULL))"
|
271
298
|
end
|
272
299
|
|
273
300
|
it "should allowing excluding by many_through_many association datasets with :conditions and composite keys" do
|
274
301
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
275
|
-
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM
|
302
|
+
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (x = 1)))))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))"
|
276
303
|
end
|
277
304
|
|
278
305
|
it "should support a :conditions option" do
|
@@ -789,6 +816,10 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
789
816
|
proc{@c1.eager_graph(Object.new)}.should raise_error(Sequel::Error)
|
790
817
|
end
|
791
818
|
|
819
|
+
it "should support association_join" do
|
820
|
+
@c1.association_join(:tags).sql.should == "SELECT * FROM artists INNER JOIN albums_artists ON (albums_artists.artist_id = artists.id) INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags ON (tags.id = albums_tags.tag_id)"
|
821
|
+
end
|
822
|
+
|
792
823
|
it "should eagerly graph a single many_through_many association" do
|
793
824
|
a = @c1.eager_graph(:tags).all
|
794
825
|
a.should == [@c1.load(:id=>1)]
|
@@ -797,6 +828,19 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
797
828
|
DB.sqls.length.should == 0
|
798
829
|
end
|
799
830
|
|
831
|
+
it "should eagerly graph a single many_through_many association using the :window_function strategy" do
|
832
|
+
def (Tag.dataset).supports_window_functions?() true end
|
833
|
+
def (Tag.dataset).columns() literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
|
834
|
+
@c1.many_through_many :tags, :clone=>:tags, :limit=>2
|
835
|
+
ds = @c1.eager_graph_with_options(:tags, :limit_strategy=>true)
|
836
|
+
ds._fetch = {:id=>1, :tags_id=>2}
|
837
|
+
a = ds.all
|
838
|
+
a.should == [@c1.load(:id=>1)]
|
839
|
+
DB.sqls.should == ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN (SELECT id, x_foreign_key_x FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id)) AS t1 WHERE (x_sequel_row_number_x <= 2)) AS tags ON (tags.x_foreign_key_x = artists.id)']
|
840
|
+
a.first.tags.should == [Tag.load(:id=>2)]
|
841
|
+
DB.sqls.length.should == 0
|
842
|
+
end
|
843
|
+
|
800
844
|
it "should eagerly graph multiple associations in a single call" do
|
801
845
|
a = @c1.eager_graph(:tags, :albums).all
|
802
846
|
a.should == [@c1.load(:id=>1)]
|
@@ -1076,3 +1120,942 @@ describe "many_through_many associations with non-column expression keys" do
|
|
1076
1120
|
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT f.l[0] FROM f INNER JOIN f AS f_0 ON (f_0.l[1] = f.r[0]) WHERE ((f_0.r[1] IN (SELECT foos.object_ids[0] FROM foos WHERE ((id = 1) AND (foos.object_ids[0] IS NOT NULL)))) AND (f.l[0] IS NOT NULL)))) LIMIT 1"]
|
1077
1121
|
end
|
1078
1122
|
end
|
1123
|
+
|
1124
|
+
describe Sequel::Model, "one_through_many" do
|
1125
|
+
before do
|
1126
|
+
class ::Artist < Sequel::Model
|
1127
|
+
attr_accessor :yyy
|
1128
|
+
columns :id
|
1129
|
+
plugin :many_through_many
|
1130
|
+
end
|
1131
|
+
class ::Tag < Sequel::Model
|
1132
|
+
columns :id, :h1, :h2
|
1133
|
+
end
|
1134
|
+
@c1 = Artist
|
1135
|
+
@c2 = Tag
|
1136
|
+
@dataset = @c2.dataset
|
1137
|
+
@dataset._fetch = {:id=>1}
|
1138
|
+
DB.reset
|
1139
|
+
end
|
1140
|
+
after do
|
1141
|
+
Object.send(:remove_const, :Artist)
|
1142
|
+
Object.send(:remove_const, :Tag)
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
|
1146
|
+
@c1.send(:define_method, :id3){id*3}
|
1147
|
+
@c1.dataset._fetch = {:id=>1}
|
1148
|
+
@c2.dataset._fetch = {:id=>4, :x_foreign_key_x=>3}
|
1149
|
+
@c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:id3
|
1150
|
+
a = @c1.eager(:tag).all
|
1151
|
+
a.should == [@c1.load(:id => 1)]
|
1152
|
+
DB.sqls.should == ['SELECT * FROM artists', "SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (3)))"]
|
1153
|
+
a.first.tag.should == @c2.load(:id=>4)
|
1154
|
+
DB.sqls.should == []
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup" do
|
1158
|
+
@c1.dataset._fetch = {:id=>1}
|
1159
|
+
@c2.dataset._fetch = {:id=>4, :x_foreign_key_x=>1}
|
1160
|
+
@c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>Sequel./(:albums_artists__artist_id, 3)
|
1161
|
+
a = @c1.eager(:tag).all
|
1162
|
+
a.should == [@c1.load(:id => 1)]
|
1163
|
+
DB.sqls.should == ['SELECT * FROM artists', "SELECT tags.*, (albums_artists.artist_id / 3) AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND ((albums_artists.artist_id / 3) IN (1)))"]
|
1164
|
+
a.first.tag.should == @c2.load(:id=>4)
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
it "should raise an error if in invalid form of through is used" do
|
1168
|
+
proc{@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id]]}.should raise_error(Sequel::Error)
|
1169
|
+
proc{@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], {:table=>:album_tags, :left=>:album_id}]}.should raise_error(Sequel::Error)
|
1170
|
+
proc{@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], :album_tags]}.should raise_error(Sequel::Error)
|
1171
|
+
end
|
1172
|
+
|
1173
|
+
it "should allow only two arguments with the :through option" do
|
1174
|
+
@c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1175
|
+
n = @c1.load(:id => 1234)
|
1176
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1'
|
1177
|
+
n.tag.should == @c2.load(:id=>1)
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
it "should be clonable" do
|
1181
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1182
|
+
@c1.many_through_many :tags, :clone=>:tag
|
1183
|
+
@c1.one_through_many :tag, :clone=>:tags
|
1184
|
+
n = @c1.load(:id => 1234)
|
1185
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1'
|
1186
|
+
n.tag.should == @c2.load(:id=>1)
|
1187
|
+
end
|
1188
|
+
|
1189
|
+
it "should use join tables given" do
|
1190
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1191
|
+
n = @c1.load(:id => 1234)
|
1192
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1'
|
1193
|
+
n.tag.should == @c2.load(:id=>1)
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
it "should handle multiple aliasing of tables" do
|
1197
|
+
begin
|
1198
|
+
class ::Album < Sequel::Model
|
1199
|
+
end
|
1200
|
+
@c1.one_through_many :album, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id], [:artists, :id, :id], [:albums_artists, :artist_id, :album_id]]
|
1201
|
+
n = @c1.load(:id => 1234)
|
1202
|
+
n.album_dataset.sql.should == 'SELECT albums.* FROM albums INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) INNER JOIN artists ON (artists.id = albums_artists.artist_id) INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) INNER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) INNER JOIN albums_artists AS albums_artists_1 ON ((albums_artists_1.album_id = albums_0.id) AND (albums_artists_1.artist_id = 1234)) LIMIT 1'
|
1203
|
+
n.album.should == Album.load(:id=>1, :x=>1)
|
1204
|
+
ensure
|
1205
|
+
Object.send(:remove_const, :Album)
|
1206
|
+
end
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
it "should use explicit class if given" do
|
1210
|
+
@c1.one_through_many :album_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag
|
1211
|
+
n = @c1.load(:id => 1234)
|
1212
|
+
n.album_tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1'
|
1213
|
+
n.album_tag.should == @c2.load(:id=>1)
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
it "should accept :left_primary_key and :right_primary_key option for primary keys to use in current and associated table" do
|
1217
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :right_primary_key=>:tag_id, :left_primary_key=>:yyy
|
1218
|
+
n = @c1.load(:id => 1234)
|
1219
|
+
n.yyy = 85
|
1220
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.tag_id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 85)) LIMIT 1'
|
1221
|
+
n.tag.should == @c2.load(:id=>1)
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
it "should handle composite keys" do
|
1225
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
1226
|
+
n = @c1.load(:id => 1234)
|
1227
|
+
n.yyy = 85
|
1228
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2) AND (albums_artists.b1 = 1234) AND (albums_artists.b2 = 85)) LIMIT 1'
|
1229
|
+
n.tag.should == @c2.load(:id=>1)
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
it "should allowing filtering by one_through_many associations" do
|
1233
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1234
|
+
@c1.filter(:tag=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
1235
|
+
end
|
1236
|
+
|
1237
|
+
it "should allowing filtering by one_through_many associations with a single through table" do
|
1238
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id]]
|
1239
|
+
@c1.filter(:tag=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists WHERE ((albums_artists.album_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
1240
|
+
end
|
1241
|
+
|
1242
|
+
it "should allowing filtering by one_through_many associations with aliased tables" do
|
1243
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums_artists, :id, :id], [:albums_artists, :album_id, :tag_id]]
|
1244
|
+
@c1.filter(:tag=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.id = albums_artists.album_id) INNER JOIN albums_artists AS albums_artists_1 ON (albums_artists_1.album_id = albums_artists_0.id) WHERE ((albums_artists_1.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
it "should allowing filtering by one_through_many associations with composite keys" do
|
1248
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
1249
|
+
@c1.filter(:tag=>@c2.load(:h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE ((albums_tags.g1 = 1234) AND (albums_tags.g2 = 85) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
1250
|
+
end
|
1251
|
+
|
1252
|
+
it "should allowing filtering by one_through_many associations with :conditions" do
|
1253
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
1254
|
+
@c1.filter(:tag=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id = 1234))))"
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
it "should allowing filtering by one_through_many associations with :conditions with a single through table" do
|
1258
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id]], :conditions=>{:name=>'A'}
|
1259
|
+
@c1.filter(:tag=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_artists ON (albums_artists.album_id = tags.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id = 1234))))"
|
1260
|
+
end
|
1261
|
+
|
1262
|
+
it "should allowing filtering by one_through_many associations with :conditions and composite keys" do
|
1263
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
1264
|
+
@c1.filter(:tag=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id = 1))))"
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
it "should allowing filtering by one_through_many associations with :order" do
|
1268
|
+
def (@c2.dataset).supports_distinct_on?; true end
|
1269
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:name
|
1270
|
+
@c1.filter(:tag=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT DISTINCT ON (albums_artists.artist_id) albums_artists.artist_id, tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) ORDER BY albums_artists.artist_id, name)) AND (tags.id = 1234))))'
|
1271
|
+
end
|
1272
|
+
|
1273
|
+
it "should allowing filtering by one_through_many associations with :order and composite keys" do
|
1274
|
+
def (@c2.dataset).supports_distinct_on?; true end
|
1275
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :order=>:name
|
1276
|
+
@c1.filter(:tag=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT DISTINCT ON (albums_artists.b1, albums_artists.b2) albums_artists.b1, albums_artists.b2, tags.id FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) ORDER BY albums_artists.b1, albums_artists.b2, name)) AND (tags.id = 1))))'
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
it "should allowing filtering by one_through_many associations with :order and :conditions" do
|
1280
|
+
def (@c2.dataset).supports_distinct_on?; true end
|
1281
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}, :order=>:name
|
1282
|
+
@c1.filter(:tag=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT DISTINCT ON (albums_artists.artist_id) albums_artists.artist_id, tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (name = 'A') ORDER BY albums_artists.artist_id, name)) AND (tags.id = 1234))))"
|
1283
|
+
end
|
1284
|
+
|
1285
|
+
it "should allowing filtering by one_through_many associations with :order and :conditions and composite keys" do
|
1286
|
+
def (@c2.dataset).supports_distinct_on?; true end
|
1287
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}, :order=>:name
|
1288
|
+
@c1.filter(:tag=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT DISTINCT ON (albums_artists.b1, albums_artists.b2) albums_artists.b1, albums_artists.b2, tags.id FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE (name = 'A') ORDER BY albums_artists.b1, albums_artists.b2, name)) AND (tags.id = 1))))"
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
it "should allowing excluding by one_through_many associations" do
|
1292
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1293
|
+
@c1.exclude(:tag=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL)))) OR (artists.id IS NULL))'
|
1294
|
+
end
|
1295
|
+
|
1296
|
+
it "should allowing excluding by one_through_many associations with composite keys" do
|
1297
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
1298
|
+
@c1.exclude(:tag=>@c2.load(:h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE ((albums_tags.g1 = 1234) AND (albums_tags.g2 = 85) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))'
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
it "should allowing excluding by one_through_many associations with :conditions" do
|
1302
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
1303
|
+
@c1.exclude(:tag=>@c2.load(:id=>1234)).sql.should == "SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id = 1234)))) OR (artists.id IS NULL))"
|
1304
|
+
end
|
1305
|
+
|
1306
|
+
it "should allowing excluding by one_through_many associations with :conditions and composite keys" do
|
1307
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
1308
|
+
@c1.exclude(:tag=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.should == "SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id = 1)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))"
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
it "should allowing filtering by multiple one_through_many associations" do
|
1312
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1313
|
+
@c1.filter(:tag=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (1234, 2345)) AND (albums_artists.artist_id IS NOT NULL))))'
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
it "should allowing filtering by multiple one_through_many associations with composite keys" do
|
1317
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
1318
|
+
@c1.filter(:tag=>[@c2.load(:h1=>1234, :h2=>85), @c2.load(:h1=>2345, :h2=>95)]).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN ((1234, 85), (2345, 95))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
1319
|
+
end
|
1320
|
+
|
1321
|
+
it "should allowing filtering by multiple one_through_many associations with :conditions" do
|
1322
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
1323
|
+
@c1.filter(:tag=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id IN (1234, 2345)))))"
|
1324
|
+
end
|
1325
|
+
|
1326
|
+
it "should allowing filtering by multiple one_through_many associations with :conditions and composite keys" do
|
1327
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
1328
|
+
@c1.filter(:tag=>[@c2.load(:id=>1, :h1=>1234, :h2=>85), @c2.load(:id=>2, :h1=>2345, :h2=>95)]).sql.should == "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id IN (1, 2)))))"
|
1329
|
+
end
|
1330
|
+
|
1331
|
+
it "should allowing excluding by multiple one_through_many associations" do
|
1332
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1333
|
+
@c1.exclude(:tag=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == 'SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (1234, 2345)) AND (albums_artists.artist_id IS NOT NULL)))) OR (artists.id IS NULL))'
|
1334
|
+
end
|
1335
|
+
|
1336
|
+
it "should allowing excluding by multiple one_through_many associations with composite keys" do
|
1337
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
1338
|
+
@c1.exclude(:tag=>[@c2.load(:h1=>1234, :h2=>85), @c2.load(:h1=>2345, :h2=>95)]).sql.should == 'SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN ((1234, 85), (2345, 95))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))'
|
1339
|
+
end
|
1340
|
+
|
1341
|
+
it "should allowing excluding by multiple one_through_many associations with :conditions" do
|
1342
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
1343
|
+
@c1.exclude(:tag=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == "SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id IN (1234, 2345))))) OR (artists.id IS NULL))"
|
1344
|
+
end
|
1345
|
+
|
1346
|
+
it "should allowing excluding by multiple one_through_many associations with :conditions and composite keys" do
|
1347
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
1348
|
+
@c1.exclude(:tag=>[@c2.load(:id=>1, :h1=>1234, :h2=>85), @c2.load(:id=>2, :h1=>2345, :h2=>95)]).sql.should == "SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id IN (1, 2))))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))"
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
it "should allowing filtering/excluding one_through_many associations with NULL values" do
|
1352
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1353
|
+
@c1.filter(:tag=>@c2.new).sql.should == 'SELECT * FROM artists WHERE \'f\''
|
1354
|
+
@c1.exclude(:tag=>@c2.new).sql.should == 'SELECT * FROM artists WHERE \'t\''
|
1355
|
+
end
|
1356
|
+
|
1357
|
+
it "should allowing filtering by one_through_many association datasets" do
|
1358
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1359
|
+
@c1.filter(:tag=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (SELECT tags.id FROM tags WHERE ((x = 1) AND (tags.id IS NOT NULL)))) AND (albums_artists.artist_id IS NOT NULL))))'
|
1360
|
+
end
|
1361
|
+
|
1362
|
+
it "should allowing filtering by one_through_many association datasets with composite keys" do
|
1363
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
1364
|
+
@c1.filter(:tag=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN (SELECT tags.h1, tags.h2 FROM tags WHERE ((x = 1) AND (tags.h1 IS NOT NULL) AND (tags.h2 IS NOT NULL)))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
it "should allowing filtering by one_through_many association datasets with :conditions" do
|
1368
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
1369
|
+
@c1.filter(:tag=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (x = 1))))))"
|
1370
|
+
end
|
1371
|
+
|
1372
|
+
it "should allowing filtering by one_through_many association datasets with :conditions and composite keys" do
|
1373
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
1374
|
+
@c1.filter(:tag=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (x = 1))))))"
|
1375
|
+
end
|
1376
|
+
|
1377
|
+
it "should allowing excluding by one_through_many association datasets" do
|
1378
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1379
|
+
@c1.exclude(:tag=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (SELECT tags.id FROM tags WHERE ((x = 1) AND (tags.id IS NOT NULL)))) AND (albums_artists.artist_id IS NOT NULL)))) OR (artists.id IS NULL))'
|
1380
|
+
end
|
1381
|
+
|
1382
|
+
it "should allowing excluding by one_through_many association datasets with composite keys" do
|
1383
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
1384
|
+
@c1.exclude(:tag=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN (SELECT tags.h1, tags.h2 FROM tags WHERE ((x = 1) AND (tags.h1 IS NOT NULL) AND (tags.h2 IS NOT NULL)))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))'
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
it "should allowing excluding by one_through_many association datasets with :conditions" do
|
1388
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}
|
1389
|
+
@c1.exclude(:tag=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (x = 1)))))) OR (artists.id IS NULL))"
|
1390
|
+
end
|
1391
|
+
|
1392
|
+
it "should allowing excluding by one_through_many association datasets with :conditions and composite keys" do
|
1393
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}
|
1394
|
+
@c1.exclude(:tag=>@c2.filter(:x=>1)).sql.should == "SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (x = 1)))))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))"
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
it "should support a :conditions option" do
|
1398
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:a=>32}
|
1399
|
+
n = @c1.load(:id => 1234)
|
1400
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) WHERE (a = 32) LIMIT 1'
|
1401
|
+
n.tag.should == @c2.load(:id=>1)
|
1402
|
+
|
1403
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>['a = ?', 42]
|
1404
|
+
n = @c1.load(:id => 1234)
|
1405
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) WHERE (a = 42) LIMIT 1'
|
1406
|
+
n.tag.should == @c2.load(:id=>1)
|
1407
|
+
end
|
1408
|
+
|
1409
|
+
it "should support an :order option" do
|
1410
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah
|
1411
|
+
n = @c1.load(:id => 1234)
|
1412
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) ORDER BY blah LIMIT 1'
|
1413
|
+
n.tag.should == @c2.load(:id=>1)
|
1414
|
+
end
|
1415
|
+
|
1416
|
+
it "should support an array for the :order option" do
|
1417
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>[:blah1, :blah2]
|
1418
|
+
n = @c1.load(:id => 1234)
|
1419
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) ORDER BY blah1, blah2 LIMIT 1'
|
1420
|
+
n.tag.should == @c2.load(:id=>1)
|
1421
|
+
end
|
1422
|
+
|
1423
|
+
it "should support a select option" do
|
1424
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>:blah
|
1425
|
+
n = @c1.load(:id => 1234)
|
1426
|
+
n.tag_dataset.sql.should == 'SELECT blah FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1'
|
1427
|
+
n.tag.should == @c2.load(:id=>1)
|
1428
|
+
end
|
1429
|
+
|
1430
|
+
it "should support an array for the select option" do
|
1431
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[Sequel::SQL::ColumnAll.new(:tags), :albums__name]
|
1432
|
+
n = @c1.load(:id => 1234)
|
1433
|
+
n.tag_dataset.sql.should == 'SELECT tags.*, albums.name FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1'
|
1434
|
+
n.tag.should == @c2.load(:id=>1)
|
1435
|
+
end
|
1436
|
+
|
1437
|
+
it "should accept a block" do
|
1438
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]] do |ds| ds.filter(:yyy=>@yyy) end
|
1439
|
+
n = @c1.load(:id => 1234)
|
1440
|
+
n.yyy = 85
|
1441
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) WHERE (yyy = 85) LIMIT 1'
|
1442
|
+
n.tag.should == @c2.load(:id=>1)
|
1443
|
+
end
|
1444
|
+
|
1445
|
+
it "should allow the :order option while accepting a block" do
|
1446
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah do |ds| ds.filter(:yyy=>@yyy) end
|
1447
|
+
n = @c1.load(:id => 1234)
|
1448
|
+
n.yyy = 85
|
1449
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) WHERE (yyy = 85) ORDER BY blah LIMIT 1'
|
1450
|
+
n.tag.should == @c2.load(:id=>1)
|
1451
|
+
end
|
1452
|
+
|
1453
|
+
it "should support a :dataset option that is used instead of the default" do
|
1454
|
+
@c1.one_through_many :tag, [[:a, :b, :c]], :dataset=>proc{Tag.join(:albums_tags, [:tag_id]).join(:albums, [:album_id]).join(:albums_artists, [:album_id]).filter(:albums_artists__artist_id=>id)}
|
1455
|
+
n = @c1.load(:id => 1234)
|
1456
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags USING (tag_id) INNER JOIN albums USING (album_id) INNER JOIN albums_artists USING (album_id) WHERE (albums_artists.artist_id = 1234) LIMIT 1'
|
1457
|
+
n.tag.should == @c2.load(:id=>1)
|
1458
|
+
end
|
1459
|
+
|
1460
|
+
it "should support a :limit option to specify an offset" do
|
1461
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>[nil, 10]
|
1462
|
+
n = @c1.load(:id => 1234)
|
1463
|
+
n.tag_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1 OFFSET 10'
|
1464
|
+
n.tag.should == @c2.load(:id=>1)
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
it "should have the :eager option affect the _dataset method" do
|
1468
|
+
@c2.many_to_many :fans
|
1469
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager=>:fans
|
1470
|
+
@c1.load(:id => 1234).tag_dataset.opts[:eager].should == {:fans=>nil}
|
1471
|
+
end
|
1472
|
+
|
1473
|
+
it "should return the associated object" do
|
1474
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1475
|
+
@c1.load(:id => 1234).tag.should == @c2.load(:id=>1)
|
1476
|
+
DB.sqls.should == ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1']
|
1477
|
+
end
|
1478
|
+
|
1479
|
+
it "should populate cache when accessed" do
|
1480
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1481
|
+
n = @c1.load(:id => 1234)
|
1482
|
+
n.associations[:tag].should == nil
|
1483
|
+
DB.sqls.should == []
|
1484
|
+
n.tag.should == @c2.load(:id=>1)
|
1485
|
+
DB.sqls.should == ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1']
|
1486
|
+
n.associations[:tag].should == n.tag
|
1487
|
+
DB.sqls.length.should == 0
|
1488
|
+
end
|
1489
|
+
|
1490
|
+
it "should use cache if available" do
|
1491
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1492
|
+
n = @c1.load(:id => 1234)
|
1493
|
+
n.associations[:tag] = nil
|
1494
|
+
n.tag.should == nil
|
1495
|
+
DB.sqls.should == []
|
1496
|
+
end
|
1497
|
+
|
1498
|
+
it "should not use cache if asked to reload" do
|
1499
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1500
|
+
n = @c1.load(:id => 1234)
|
1501
|
+
n.associations[:tag] = nil
|
1502
|
+
DB.sqls.should == []
|
1503
|
+
n.tag(true).should == @c2.load(:id=>1)
|
1504
|
+
DB.sqls.should == ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 1']
|
1505
|
+
n.associations[:tag].should == n.tag
|
1506
|
+
DB.sqls.length.should == 0
|
1507
|
+
end
|
1508
|
+
|
1509
|
+
it "should not add associations methods directly to class" do
|
1510
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1511
|
+
im = @c1.instance_methods.collect{|x| x.to_s}
|
1512
|
+
im.should(include('tag'))
|
1513
|
+
im.should(include('tag_dataset'))
|
1514
|
+
im2 = @c1.instance_methods(false).collect{|x| x.to_s}
|
1515
|
+
im2.should_not(include('tag'))
|
1516
|
+
im2.should_not(include('tag_dataset'))
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
it "should support after_load association callback" do
|
1520
|
+
h = []
|
1521
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :after_load=>:al
|
1522
|
+
@c1.class_eval do
|
1523
|
+
self::Foo = h
|
1524
|
+
def al(v)
|
1525
|
+
model::Foo << v.pk * 20
|
1526
|
+
end
|
1527
|
+
end
|
1528
|
+
@c2.dataset._fetch = [{:id=>20}]
|
1529
|
+
p = @c1.load(:id=>10, :parent_id=>20)
|
1530
|
+
p.tag
|
1531
|
+
h.should == [400]
|
1532
|
+
p.tag.pk.should == 20
|
1533
|
+
end
|
1534
|
+
end
|
1535
|
+
|
1536
|
+
describe "Sequel::Plugins::OneThroughMany eager loading methods" do
|
1537
|
+
before do
|
1538
|
+
class ::Artist < Sequel::Model
|
1539
|
+
plugin :many_through_many
|
1540
|
+
one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
1541
|
+
one_through_many :other_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>:Tag
|
1542
|
+
one_through_many :album, [[:albums_artists, :artist_id, :album_id]]
|
1543
|
+
one_through_many :artist, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id]]
|
1544
|
+
end
|
1545
|
+
class ::Tag < Sequel::Model
|
1546
|
+
plugin :many_through_many
|
1547
|
+
one_through_many :track, [[:albums_tags, :tag_id, :album_id], [:albums, :id, :id]], :right_primary_key=>:album_id
|
1548
|
+
end
|
1549
|
+
class ::Album < Sequel::Model
|
1550
|
+
end
|
1551
|
+
class ::Track < Sequel::Model
|
1552
|
+
end
|
1553
|
+
Artist.dataset.columns(:id)._fetch = proc do |sql|
|
1554
|
+
h = {:id => 1}
|
1555
|
+
if sql =~ /FROM artists LEFT OUTER JOIN albums_artists/
|
1556
|
+
h[:tag_id] = 2
|
1557
|
+
h[:album_id] = 3 if sql =~ /LEFT OUTER JOIN albums AS album/
|
1558
|
+
h[:track_id] = 4 if sql =~ /LEFT OUTER JOIN tracks AS track/
|
1559
|
+
h[:other_tag_id] = 9 if sql =~ /other_tag\.id AS other_tag_id/
|
1560
|
+
h[:artist_id] = 10 if sql =~ /artists_0\.id AS artist_id/
|
1561
|
+
end
|
1562
|
+
h
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
Tag.dataset._fetch = proc do |sql|
|
1566
|
+
h = {:id => 2}
|
1567
|
+
if sql =~ /albums_artists.artist_id IN \(([18])\)/
|
1568
|
+
h[:x_foreign_key_x] = $1.to_i
|
1569
|
+
elsif sql =~ /\(\(albums_artists.b1, albums_artists.b2\) IN \(\(1, 8\)\)\)/
|
1570
|
+
h.merge!(:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>8)
|
1571
|
+
end
|
1572
|
+
h[:tag_id] = h.delete(:id) if sql =~ /albums_artists.artist_id IN \(8\)/
|
1573
|
+
h
|
1574
|
+
end
|
1575
|
+
|
1576
|
+
Album.dataset._fetch = proc do |sql|
|
1577
|
+
h = {:id => 3}
|
1578
|
+
h[:x_foreign_key_x] = 1 if sql =~ /albums_artists.artist_id IN \(1\)/
|
1579
|
+
h
|
1580
|
+
end
|
1581
|
+
|
1582
|
+
Track.dataset._fetch = proc do |sql|
|
1583
|
+
h = {:id => 4}
|
1584
|
+
h[:x_foreign_key_x] = 2 if sql =~ /albums_tags.tag_id IN \(2\)/
|
1585
|
+
h
|
1586
|
+
end
|
1587
|
+
|
1588
|
+
@c1 = Artist
|
1589
|
+
DB.reset
|
1590
|
+
end
|
1591
|
+
after do
|
1592
|
+
[:Artist, :Tag, :Album, :Track].each{|x| Object.send(:remove_const, x)}
|
1593
|
+
end
|
1594
|
+
|
1595
|
+
it "should eagerly load a single one_through_many association" do
|
1596
|
+
a = @c1.eager(:tag).all
|
1597
|
+
a.should == [@c1.load(:id=>1)]
|
1598
|
+
DB.sqls.should == ['SELECT * FROM artists', 'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))']
|
1599
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1600
|
+
DB.sqls.length.should == 0
|
1601
|
+
end
|
1602
|
+
|
1603
|
+
it "should eagerly load multiple associations in a single call" do
|
1604
|
+
a = @c1.eager(:tag, :album).all
|
1605
|
+
a.should == [@c1.load(:id=>1)]
|
1606
|
+
sqls = DB.sqls
|
1607
|
+
sqls.length.should == 3
|
1608
|
+
sqls[0].should == 'SELECT * FROM artists'
|
1609
|
+
sqls[1..-1].should(include('SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))'))
|
1610
|
+
sqls[1..-1].should(include('SELECT albums.*, albums_artists.artist_id AS x_foreign_key_x FROM albums INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))'))
|
1611
|
+
a = a.first
|
1612
|
+
a.tag.should == Tag.load(:id=>2)
|
1613
|
+
a.album.should == Album.load(:id=>3)
|
1614
|
+
DB.sqls.length.should == 0
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
it "should eagerly load multiple associations in separate" do
|
1618
|
+
a = @c1.eager(:tag).eager(:album).all
|
1619
|
+
a.should == [@c1.load(:id=>1)]
|
1620
|
+
sqls = DB.sqls
|
1621
|
+
sqls.length.should == 3
|
1622
|
+
sqls[0].should == 'SELECT * FROM artists'
|
1623
|
+
sqls[1..-1].should(include('SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))'))
|
1624
|
+
sqls[1..-1].should(include('SELECT albums.*, albums_artists.artist_id AS x_foreign_key_x FROM albums INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))'))
|
1625
|
+
a = a.first
|
1626
|
+
a.tag.should == Tag.load(:id=>2)
|
1627
|
+
a.album.should == Album.load(:id=>3)
|
1628
|
+
DB.sqls.length.should == 0
|
1629
|
+
end
|
1630
|
+
|
1631
|
+
it "should allow cascading of eager loading for associations of associated models" do
|
1632
|
+
a = @c1.eager(:tag=>:track).all
|
1633
|
+
a.should == [@c1.load(:id=>1)]
|
1634
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1635
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))',
|
1636
|
+
'SELECT tracks.*, albums_tags.tag_id AS x_foreign_key_x FROM tracks INNER JOIN albums ON (albums.id = tracks.album_id) INNER JOIN albums_tags ON ((albums_tags.album_id = albums.id) AND (albums_tags.tag_id IN (2)))']
|
1637
|
+
a = a.first
|
1638
|
+
a.tag.should == Tag.load(:id=>2)
|
1639
|
+
a.tag.track.should == Track.load(:id=>4)
|
1640
|
+
DB.sqls.length.should == 0
|
1641
|
+
end
|
1642
|
+
|
1643
|
+
it "should cascade eagerly loading when the :eager association option is used" do
|
1644
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager=>:track
|
1645
|
+
a = @c1.eager(:tag).all
|
1646
|
+
a.should == [@c1.load(:id=>1)]
|
1647
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1648
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))',
|
1649
|
+
'SELECT tracks.*, albums_tags.tag_id AS x_foreign_key_x FROM tracks INNER JOIN albums ON (albums.id = tracks.album_id) INNER JOIN albums_tags ON ((albums_tags.album_id = albums.id) AND (albums_tags.tag_id IN (2)))']
|
1650
|
+
a = a.first
|
1651
|
+
a.tag.should == Tag.load(:id=>2)
|
1652
|
+
a.tag.track.should == Track.load(:id=>4)
|
1653
|
+
DB.sqls.length.should == 0
|
1654
|
+
end
|
1655
|
+
|
1656
|
+
it "should respect :eager when lazily loading an association" do
|
1657
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager=>:track
|
1658
|
+
a = @c1.load(:id=>1)
|
1659
|
+
a.tag.should == Tag.load(:id=>2)
|
1660
|
+
DB.sqls.should == ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1)) LIMIT 1',
|
1661
|
+
'SELECT tracks.*, albums_tags.tag_id AS x_foreign_key_x FROM tracks INNER JOIN albums ON (albums.id = tracks.album_id) INNER JOIN albums_tags ON ((albums_tags.album_id = albums.id) AND (albums_tags.tag_id IN (2)))']
|
1662
|
+
a.tag.track.should == Track.load(:id=>4)
|
1663
|
+
DB.sqls.length.should == 0
|
1664
|
+
end
|
1665
|
+
|
1666
|
+
it "should raise error if attempting to eagerly load an association using :eager_graph option" do
|
1667
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:track
|
1668
|
+
proc{@c1.eager(:tag).all}.should raise_error(Sequel::Error)
|
1669
|
+
end
|
1670
|
+
|
1671
|
+
it "should respect :eager_graph when lazily loading an association" do
|
1672
|
+
Tag.dataset._fetch = {:id=>2, :track_id=>4}
|
1673
|
+
Tag.dataset.extend(Module.new {
|
1674
|
+
def columns
|
1675
|
+
[:id]
|
1676
|
+
end
|
1677
|
+
})
|
1678
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:track
|
1679
|
+
a = @c1.load(:id=>1)
|
1680
|
+
a.tag
|
1681
|
+
DB.sqls.should == [ 'SELECT tags.id, track.id AS track_id FROM (SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1)) LIMIT 1) AS tags LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tags.id) LEFT OUTER JOIN albums ON (albums.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks AS track ON (track.album_id = albums.id)']
|
1682
|
+
a.tag.should == Tag.load(:id=>2)
|
1683
|
+
a.tag.track.should == Track.load(:id=>4)
|
1684
|
+
DB.sqls.length.should == 0
|
1685
|
+
end
|
1686
|
+
|
1687
|
+
it "should respect :conditions when eagerly loading" do
|
1688
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:a=>32}
|
1689
|
+
a = @c1.eager(:tag).all
|
1690
|
+
a.should == [@c1.load(:id=>1)]
|
1691
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1692
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) WHERE (a = 32)']
|
1693
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1694
|
+
DB.sqls.length.should == 0
|
1695
|
+
end
|
1696
|
+
|
1697
|
+
it "should respect :order when eagerly loading" do
|
1698
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah
|
1699
|
+
a = @c1.eager(:tag).all
|
1700
|
+
a.should == [@c1.load(:id=>1)]
|
1701
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1702
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) ORDER BY blah']
|
1703
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1704
|
+
DB.sqls.length.should == 0
|
1705
|
+
end
|
1706
|
+
|
1707
|
+
it "should use the association's block when eager loading by default" do
|
1708
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]] do |ds| ds.filter(:a) end
|
1709
|
+
a = @c1.eager(:tag).all
|
1710
|
+
a.should == [@c1.load(:id=>1)]
|
1711
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1712
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) WHERE a']
|
1713
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1714
|
+
DB.sqls.length.should == 0
|
1715
|
+
end
|
1716
|
+
|
1717
|
+
it "should use the :eager_block option when eager loading if given" do
|
1718
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_block=>proc{|ds| ds.filter(:b)} do |ds| ds.filter(:a) end
|
1719
|
+
a = @c1.eager(:tag).all
|
1720
|
+
a.should == [@c1.load(:id=>1)]
|
1721
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1722
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) WHERE b']
|
1723
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1724
|
+
DB.sqls.length.should == 0
|
1725
|
+
end
|
1726
|
+
|
1727
|
+
it "should respect the :limit option on a one_through_many association" do
|
1728
|
+
@c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1]
|
1729
|
+
Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5}, {:x_foreign_key_x=>1, :id=>6}]
|
1730
|
+
a = @c1.eager(:second_tag).all
|
1731
|
+
a.should == [@c1.load(:id=>1)]
|
1732
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1733
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))']
|
1734
|
+
a.first.second_tag.should == Tag.load(:id=>6)
|
1735
|
+
DB.sqls.length.should == 0
|
1736
|
+
end
|
1737
|
+
|
1738
|
+
it "should eagerly load a single one_through_many association using the :distinct_on strategy" do
|
1739
|
+
Tag.dataset.meta_def(:supports_distinct_on?){true}
|
1740
|
+
@c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :order=>:name
|
1741
|
+
Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5}]
|
1742
|
+
a = @c1.eager(:second_tag).all
|
1743
|
+
a.should == [@c1.load(:id=>1)]
|
1744
|
+
DB.sqls.should == ['SELECT * FROM artists', "SELECT DISTINCT ON (albums_artists.artist_id) tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) ORDER BY albums_artists.artist_id, name"]
|
1745
|
+
a.first.second_tag.should == Tag.load(:id=>5)
|
1746
|
+
DB.sqls.length.should == 0
|
1747
|
+
end
|
1748
|
+
|
1749
|
+
it "should eagerly load a single one_through_many association using the :window_function strategy" do
|
1750
|
+
Tag.dataset.meta_def(:supports_window_functions?){true}
|
1751
|
+
@c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name
|
1752
|
+
Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5}]
|
1753
|
+
a = @c1.eager(:second_tag).all
|
1754
|
+
a.should == [@c1.load(:id=>1)]
|
1755
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1756
|
+
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))) AS t1 WHERE (x_sequel_row_number_x = 2)']
|
1757
|
+
a.first.second_tag.should == Tag.load(:id=>5)
|
1758
|
+
DB.sqls.length.should == 0
|
1759
|
+
end
|
1760
|
+
|
1761
|
+
it "should respect the :limit option on a one_through_many association with composite primary keys on the main table using a :window_function strategy" do
|
1762
|
+
Tag.dataset.meta_def(:supports_window_functions?){true}
|
1763
|
+
@c1.set_primary_key([:id1, :id2])
|
1764
|
+
@c1.columns :id1, :id2
|
1765
|
+
|
1766
|
+
@c1.one_through_many :second_tag, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name
|
1767
|
+
ds = @c1.eager(:second_tag)
|
1768
|
+
ds._fetch = {:id1=>1, :id2=>2}
|
1769
|
+
Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]
|
1770
|
+
a = ds.all
|
1771
|
+
a.should == [@c1.load(:id1=>1, :id2=>2)]
|
1772
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1773
|
+
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x, row_number() OVER (PARTITION BY albums_artists.artist_id1, albums_artists.artist_id2 ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2))))) AS t1 WHERE (x_sequel_row_number_x = 2)']
|
1774
|
+
a.first.second_tag.should == Tag.load(:id=>5)
|
1775
|
+
DB.sqls.length.should == 0
|
1776
|
+
end
|
1777
|
+
|
1778
|
+
it "should raise an error when attempting to eagerly load an association with the :allow_eager option set to false" do
|
1779
|
+
proc{@c1.eager(:tag).all}.should_not raise_error
|
1780
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :allow_eager=>false
|
1781
|
+
proc{@c1.eager(:tag).all}.should raise_error(Sequel::Error)
|
1782
|
+
end
|
1783
|
+
|
1784
|
+
it "should respect the association's :select option" do
|
1785
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>:tags__name
|
1786
|
+
a = @c1.eager(:tag).all
|
1787
|
+
a.should == [@c1.load(:id=>1)]
|
1788
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1789
|
+
'SELECT tags.name, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))']
|
1790
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1791
|
+
DB.sqls.length.should == 0
|
1792
|
+
end
|
1793
|
+
|
1794
|
+
it "should respect one_through_many association's :left_primary_key and :right_primary_key options" do
|
1795
|
+
@c1.send(:define_method, :yyy){values[:yyy]}
|
1796
|
+
@c1.dataset._fetch = {:id=>1, :yyy=>8}
|
1797
|
+
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
1798
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
|
1799
|
+
a = @c1.eager(:tag).all
|
1800
|
+
a.should == [@c1.load(:id=>1, :yyy=>8)]
|
1801
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1802
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.tag_id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (8)))']
|
1803
|
+
a.first.tag.should == Tag.load(:tag_id=>2)
|
1804
|
+
DB.sqls.length.should == 0
|
1805
|
+
end
|
1806
|
+
|
1807
|
+
it "should handle composite keys" do
|
1808
|
+
@c1.send(:define_method, :yyy){values[:yyy]}
|
1809
|
+
@c1.dataset._fetch = {:id=>1, :yyy=>8}
|
1810
|
+
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
1811
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
1812
|
+
a = @c1.eager(:tag).all
|
1813
|
+
a.should == [@c1.load(:id=>1, :yyy=>8)]
|
1814
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1815
|
+
'SELECT tags.*, albums_artists.b1 AS x_foreign_key_0_x, albums_artists.b2 AS x_foreign_key_1_x FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2) AND ((albums_artists.b1, albums_artists.b2) IN ((1, 8))))']
|
1816
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1817
|
+
DB.sqls.length.should == 0
|
1818
|
+
end
|
1819
|
+
|
1820
|
+
it "should respect :after_load callbacks on associations when eager loading" do
|
1821
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :after_load=>lambda{|o, a| o[:id] *= 2; a[:id] *= 3}
|
1822
|
+
a = @c1.eager(:tag).all
|
1823
|
+
a.should == [@c1.load(:id=>2)]
|
1824
|
+
DB.sqls.should == ['SELECT * FROM artists',
|
1825
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))']
|
1826
|
+
a.first.tag.should == Tag.load(:id=>6)
|
1827
|
+
DB.sqls.length.should == 0
|
1828
|
+
end
|
1829
|
+
|
1830
|
+
it "should support association_join" do
|
1831
|
+
@c1.association_join(:tag).sql.should == "SELECT * FROM artists INNER JOIN albums_artists ON (albums_artists.artist_id = artists.id) INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)"
|
1832
|
+
end
|
1833
|
+
|
1834
|
+
it "should eagerly graph a single one_through_many association" do
|
1835
|
+
a = @c1.eager_graph(:tag).all
|
1836
|
+
a.should == [@c1.load(:id=>1)]
|
1837
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)']
|
1838
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1839
|
+
DB.sqls.length.should == 0
|
1840
|
+
end
|
1841
|
+
|
1842
|
+
it "should eagerly graph a single one_through_many association using the :distinct_on strategy" do
|
1843
|
+
def (Tag.dataset).supports_distinct_on?() true end
|
1844
|
+
ds = @c1.eager_graph_with_options(:tag, :limit_strategy=>true)
|
1845
|
+
ds._fetch = {:id=>1, :tag_id=>2}
|
1846
|
+
a = ds.all
|
1847
|
+
a.should == [@c1.load(:id=>1)]
|
1848
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN (SELECT DISTINCT ON (albums_artists.artist_id) tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) ORDER BY albums_artists.artist_id) AS tag ON (tag.x_foreign_key_x = artists.id)']
|
1849
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1850
|
+
DB.sqls.length.should == 0
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
it "should eagerly graph a single one_through_many association using the :window_function strategy" do
|
1854
|
+
def (Tag.dataset).supports_window_functions?() true end
|
1855
|
+
def (Tag.dataset).columns() literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
|
1856
|
+
ds = @c1.eager_graph_with_options(:tag, :limit_strategy=>true)
|
1857
|
+
ds._fetch = {:id=>1, :tag_id=>2}
|
1858
|
+
a = ds.all
|
1859
|
+
a.should == [@c1.load(:id=>1)]
|
1860
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN (SELECT id, x_foreign_key_x FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id)) AS t1 WHERE (x_sequel_row_number_x = 1)) AS tag ON (tag.x_foreign_key_x = artists.id)']
|
1861
|
+
a.first.tag.should == Tag.load(:id=>2)
|
1862
|
+
DB.sqls.length.should == 0
|
1863
|
+
end
|
1864
|
+
|
1865
|
+
it "should eagerly graph multiple associations in a single call" do
|
1866
|
+
a = @c1.eager_graph(:tag, :album).all
|
1867
|
+
a.should == [@c1.load(:id=>1)]
|
1868
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id, album.id AS album_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS album ON (album.id = albums_artists_0.album_id)']
|
1869
|
+
a = a.first
|
1870
|
+
a.tag.should == Tag.load(:id=>2)
|
1871
|
+
a.album.should == Album.load(:id=>3)
|
1872
|
+
DB.sqls.length.should == 0
|
1873
|
+
end
|
1874
|
+
|
1875
|
+
it "should eagerly graph multiple associations in separate calls" do
|
1876
|
+
a = @c1.eager_graph(:tag).eager_graph(:album).all
|
1877
|
+
a.should == [@c1.load(:id=>1)]
|
1878
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id, album.id AS album_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS album ON (album.id = albums_artists_0.album_id)']
|
1879
|
+
a = a.first
|
1880
|
+
a.tag.should == Tag.load(:id=>2)
|
1881
|
+
a.album.should == Album.load(:id=>3)
|
1882
|
+
DB.sqls.length.should == 0
|
1883
|
+
end
|
1884
|
+
|
1885
|
+
it "should allow cascading of eager graphing for associations of associated models" do
|
1886
|
+
a = @c1.eager_graph(:tag=>:track).all
|
1887
|
+
a.should == [@c1.load(:id=>1)]
|
1888
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id, track.id AS track_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tag.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks AS track ON (track.album_id = albums_0.id)']
|
1889
|
+
a = a.first
|
1890
|
+
a.tag.should == Tag.load(:id=>2)
|
1891
|
+
a.tag.track.should == Track.load(:id=>4)
|
1892
|
+
DB.sqls.length.should == 0
|
1893
|
+
end
|
1894
|
+
|
1895
|
+
it "should eager graph multiple associations from the same table" do
|
1896
|
+
a = @c1.eager_graph(:tag, :other_tag).all
|
1897
|
+
a.should == [@c1.load(:id=>1)]
|
1898
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id, other_tag.id AS other_tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.album_id = albums_0.id) LEFT OUTER JOIN tags AS other_tag ON (other_tag.id = albums_tags_0.tag_id)']
|
1899
|
+
a = a.first
|
1900
|
+
a.tag.should == Tag.load(:id=>2)
|
1901
|
+
a.other_tag.should == Tag.load(:id=>9)
|
1902
|
+
DB.sqls.length.should == 0
|
1903
|
+
end
|
1904
|
+
|
1905
|
+
it "should eager graph a self_referential association" do
|
1906
|
+
ds = @c1.eager_graph(:tag, :artist)
|
1907
|
+
ds._fetch = {:id=>1, :tag_id=>2, :artist_id=>10}
|
1908
|
+
a = ds.all
|
1909
|
+
a.should == [@c1.load(:id=>1)]
|
1910
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id, artist.id AS artist_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) LEFT OUTER JOIN albums_artists AS albums_artists_1 ON (albums_artists_1.album_id = albums_0.id) LEFT OUTER JOIN artists AS artist ON (artist.id = albums_artists_1.artist_id)']
|
1911
|
+
a = a.first
|
1912
|
+
a.tag.should == Tag.load(:id=>2)
|
1913
|
+
a.artist.should == @c1.load(:id=>10)
|
1914
|
+
DB.sqls.length.should == 0
|
1915
|
+
end
|
1916
|
+
|
1917
|
+
it "should be able to use eager and eager_graph together" do
|
1918
|
+
a = @c1.eager_graph(:tag).eager(:album).all
|
1919
|
+
a.should == [@c1.load(:id=>1)]
|
1920
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)',
|
1921
|
+
'SELECT albums.*, albums_artists.artist_id AS x_foreign_key_x FROM albums INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))']
|
1922
|
+
a = a.first
|
1923
|
+
a.tag.should == Tag.load(:id=>2)
|
1924
|
+
a.album.should == Album.load(:id=>3)
|
1925
|
+
DB.sqls.length.should == 0
|
1926
|
+
end
|
1927
|
+
|
1928
|
+
it "should handle no associated records when eagerly graphing a single one_through_many association" do
|
1929
|
+
ds = @c1.eager_graph(:tag)
|
1930
|
+
ds._fetch = {:id=>1, :tag_id=>nil}
|
1931
|
+
a = ds.all
|
1932
|
+
a.should == [@c1.load(:id=>1)]
|
1933
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)']
|
1934
|
+
a.first.tag.should == nil
|
1935
|
+
DB.sqls.length.should == 0
|
1936
|
+
end
|
1937
|
+
|
1938
|
+
it "should handle no associated records when eagerly graphing multiple one_through_many associations" do
|
1939
|
+
ds = @c1.eager_graph(:tag, :album)
|
1940
|
+
ds._fetch = [{:id=>1, :tag_id=>5, :album_id=>6}, {:id=>7, :tag_id=>nil, :albums_0_id=>nil}]
|
1941
|
+
a = ds.all
|
1942
|
+
a.should == [@c1.load(:id=>1), @c1.load(:id=>7)]
|
1943
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id, album.id AS album_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS album ON (album.id = albums_artists_0.album_id)']
|
1944
|
+
a.first.tag.should == Tag.load(:id=>5)
|
1945
|
+
a.first.album.should == Album.load(:id=>6)
|
1946
|
+
a.last.tag.should == nil
|
1947
|
+
a.last.album.should == nil
|
1948
|
+
DB.sqls.length.should == 0
|
1949
|
+
end
|
1950
|
+
|
1951
|
+
it "should handle missing associated records when cascading eager graphing for associations of associated models" do
|
1952
|
+
ds = @c1.eager_graph(:tag=>:track)
|
1953
|
+
ds._fetch = [{:id=>1, :tag_id=>2, :track_id=>nil}, {:id=>2, :tag_id=>nil, :tracks_id=>nil}]
|
1954
|
+
a = ds.all
|
1955
|
+
a.should == [@c1.load(:id=>1), @c1.load(:id=>2)]
|
1956
|
+
DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id, track.id AS track_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tag.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks AS track ON (track.album_id = albums_0.id)']
|
1957
|
+
a.last.tag.should == nil
|
1958
|
+
a = a.first
|
1959
|
+
a.tag.should == Tag.load(:id=>2)
|
1960
|
+
a.tag.track.should == nil
|
1961
|
+
DB.sqls.length.should == 0
|
1962
|
+
end
|
1963
|
+
|
1964
|
+
it "eager graphing should respect :left_primary_key and :right_primary_key options" do
|
1965
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
|
1966
|
+
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
1967
|
+
Tag.dataset.meta_def(:columns){[:id, :tag_id]}
|
1968
|
+
ds = @c1.eager_graph(:tag)
|
1969
|
+
ds._fetch = {:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4}
|
1970
|
+
a = ds.all
|
1971
|
+
a.should == [@c1.load(:id=>1, :yyy=>8)]
|
1972
|
+
DB.sqls.should == ['SELECT artists.id, artists.yyy, tag.id AS tag_id, tag.tag_id AS tag_tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.yyy) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.tag_id = albums_tags.tag_id)']
|
1973
|
+
a.first.tag.should == Tag.load(:id=>2, :tag_id=>4)
|
1974
|
+
DB.sqls.length.should == 0
|
1975
|
+
end
|
1976
|
+
|
1977
|
+
it "eager graphing should respect composite keys" do
|
1978
|
+
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:id, :tag_id], :left_primary_key=>[:id, :yyy]
|
1979
|
+
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
1980
|
+
Tag.dataset.meta_def(:columns){[:id, :tag_id]}
|
1981
|
+
ds = @c1.eager_graph(:tag)
|
1982
|
+
ds._fetch = {:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4}
|
1983
|
+
a = ds.all
|
1984
|
+
a.should == [@c1.load(:id=>1, :yyy=>8)]
|
1985
|
+
DB.sqls.should == ['SELECT artists.id, artists.yyy, tag.id AS tag_id, tag.tag_id AS tag_tag_id FROM artists LEFT OUTER JOIN albums_artists ON ((albums_artists.b1 = artists.id) AND (albums_artists.b2 = artists.yyy)) LEFT OUTER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) LEFT OUTER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) LEFT OUTER JOIN tags AS tag ON ((tag.id = albums_tags.g1) AND (tag.tag_id = albums_tags.g2))']
|
1986
|
+
a.first.tag.should == Tag.load(:id=>2, :tag_id=>4)
|
1987
|
+
DB.sqls.length.should == 0
|
1988
|
+
end
|
1989
|
+
|
1990
|
+
it "should respect the association's :graph_select option" do
|
1991
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :graph_select=>:b
|
1992
|
+
ds = @c1.eager_graph(:tag)
|
1993
|
+
ds._fetch = {:id=>1, :b=>2}
|
1994
|
+
a = ds.all
|
1995
|
+
a.should == [@c1.load(:id=>1)]
|
1996
|
+
DB.sqls.should == ['SELECT artists.id, tag.b FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)']
|
1997
|
+
a.first.tag.should == Tag.load(:b=>2)
|
1998
|
+
DB.sqls.length.should == 0
|
1999
|
+
end
|
2000
|
+
|
2001
|
+
it "should respect the association's :graph_join_type option" do
|
2002
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :graph_join_type=>:inner
|
2003
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists INNER JOIN albums_artists ON (albums_artists.artist_id = artists.id) INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)'
|
2004
|
+
end
|
2005
|
+
|
2006
|
+
it "should respect the association's :join_type option on through" do
|
2007
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id, :join_type=>:natural}, [:albums_tags, :album_id, :tag_id]], :graph_join_type=>:inner
|
2008
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists INNER JOIN albums_artists ON (albums_artists.artist_id = artists.id) NATURAL JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)'
|
2009
|
+
end
|
2010
|
+
|
2011
|
+
it "should respect the association's :conditions option" do
|
2012
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :conditions=>{:a=>32}
|
2013
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON ((tag.id = albums_tags.tag_id) AND (tag.a = 32))'
|
2014
|
+
end
|
2015
|
+
|
2016
|
+
it "should respect the association's :graph_conditions option" do
|
2017
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :graph_conditions=>{:a=>42}
|
2018
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON ((tag.id = albums_tags.tag_id) AND (tag.a = 42))'
|
2019
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :graph_conditions=>{:a=>42}, :conditions=>{:a=>32}
|
2020
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON ((tag.id = albums_tags.tag_id) AND (tag.a = 42))'
|
2021
|
+
end
|
2022
|
+
|
2023
|
+
it "should respect the association's :conditions option on through" do
|
2024
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id, :conditions=>{:a=>42}}, [:albums_tags, :album_id, :tag_id]]
|
2025
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON ((albums.id = albums_artists.album_id) AND (albums.a = 42)) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)'
|
2026
|
+
end
|
2027
|
+
|
2028
|
+
it "should respect the association's :graph_block option" do
|
2029
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :graph_block=>proc{|ja,lja,js| {Sequel.qualify(ja, :active)=>true}}
|
2030
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON ((tag.id = albums_tags.tag_id) AND (tag.active IS TRUE))'
|
2031
|
+
end
|
2032
|
+
|
2033
|
+
it "should respect the association's :block option on through" do
|
2034
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id, :block=>proc{|ja,lja,js| {Sequel.qualify(ja, :active)=>true}}}, [:albums_tags, :album_id, :tag_id]]
|
2035
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON ((albums.id = albums_artists.album_id) AND (albums.active IS TRUE)) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)'
|
2036
|
+
end
|
2037
|
+
|
2038
|
+
it "should respect the association's :graph_only_conditions option" do
|
2039
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :graph_only_conditions=>{:a=>32}
|
2040
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.a = 32)'
|
2041
|
+
end
|
2042
|
+
|
2043
|
+
it "should respect the association's :only_conditions option on through" do
|
2044
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id, :only_conditions=>{:a=>42}}, [:albums_tags, :album_id, :tag_id]]
|
2045
|
+
@c1.eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.a = 42) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)'
|
2046
|
+
end
|
2047
|
+
|
2048
|
+
it "should create unique table aliases for all associations" do
|
2049
|
+
@c1.eager_graph(:artist=>{:artist=>:artist}).sql.should == "SELECT artists.id, artist.id AS artist_id, artist_0.id AS artist_0_id, artist_1.id AS artist_1_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.album_id = albums.id) LEFT OUTER JOIN artists AS artist ON (artist.id = albums_artists_0.artist_id) LEFT OUTER JOIN albums_artists AS albums_artists_1 ON (albums_artists_1.artist_id = artist.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_1.album_id) LEFT OUTER JOIN albums_artists AS albums_artists_2 ON (albums_artists_2.album_id = albums_0.id) LEFT OUTER JOIN artists AS artist_0 ON (artist_0.id = albums_artists_2.artist_id) LEFT OUTER JOIN albums_artists AS albums_artists_3 ON (albums_artists_3.artist_id = artist_0.id) LEFT OUTER JOIN albums AS albums_1 ON (albums_1.id = albums_artists_3.album_id) LEFT OUTER JOIN albums_artists AS albums_artists_4 ON (albums_artists_4.album_id = albums_1.id) LEFT OUTER JOIN artists AS artist_1 ON (artist_1.id = albums_artists_4.artist_id)"
|
2050
|
+
end
|
2051
|
+
|
2052
|
+
it "should respect the association's :order" do
|
2053
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[:blah1, :blah2]
|
2054
|
+
@c1.order(:artists__blah2, :artists__blah3).eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3, tag.blah1, tag.blah2'
|
2055
|
+
end
|
2056
|
+
|
2057
|
+
it "should only qualify unqualified symbols, identifiers, or ordered versions in association's :order" do
|
2058
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel.desc(:blah__id), :blah__id, :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
|
2059
|
+
@c1.order(:artists__blah2, :artists__blah3).eager_graph(:tag).sql.should == 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3, tag.blah__id, tag.blah__id DESC, blah.id DESC, blah.id, tag.album_id, tag.album_id DESC, 1, RANDOM(), b.a'
|
2060
|
+
end
|
2061
|
+
end
|