Skip to content

Commit 9d30ea3

Browse files
committed
Add tracking of join options for jsonapi-authorization gem
1 parent eb43272 commit 9d30ea3

File tree

2 files changed

+65
-45
lines changed

2 files changed

+65
-45
lines changed

Diff for: lib/jsonapi/active_relation/join_manager.rb

+8-2
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,15 @@ def perform_joins(records, options)
147147
related_resource_klass = join_details[:related_resource_klass]
148148
join_type = relationship_details[:join_type]
149149

150+
join_options = {
151+
relationship: relationship,
152+
relationship_details: relationship_details,
153+
related_resource_klass: related_resource_klass,
154+
}
155+
150156
if relationship == :root
151157
unless source_relationship
152-
add_join_details('', {alias: resource_klass._table_name, join_type: :root})
158+
add_join_details('', {alias: resource_klass._table_name, join_type: :root, join_options: join_options})
153159
end
154160
next
155161
end
@@ -163,7 +169,7 @@ def perform_joins(records, options)
163169
options: options)
164170
}
165171

166-
details = {alias: self.class.alias_from_arel_node(join_node), join_type: join_type}
172+
details = {alias: self.class.alias_from_arel_node(join_node), join_type: join_type, join_options: join_options}
167173

168174
if relationship == source_relationship
169175
if relationship.polymorphic? && relationship.belongs_to?

Diff for: test/unit/active_relation_resource_finder/join_manager_test.rb

+57-43
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def test_no_added_joins
2323
records = join_manager.join(records, {})
2424
assert_equal 'SELECT "posts".* FROM "posts"', records.to_sql
2525

26-
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details)
26+
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options))
2727
end
2828

2929
def test_add_single_join
@@ -32,8 +32,22 @@ def test_add_single_join
3232
records = PostResource.records({})
3333
records = join_manager.join(records, {})
3434
assert_equal 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "posts_tags" ON "posts_tags"."post_id" = "posts"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "posts_tags"."tag_id"', records.to_sql
35-
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details)
36-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)))
35+
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options))
36+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options))
37+
end
38+
39+
def test_joins_have_join_options
40+
filters = {'tags' => ['1']}
41+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, filters: filters)
42+
records = PostResource.records({})
43+
records = join_manager.join(records, {})
44+
assert_equal 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "posts_tags" ON "posts_tags"."post_id" = "posts"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "posts_tags"."tag_id"', records.to_sql
45+
46+
source_join_options = join_manager.source_join_details[:join_options]
47+
assert_array_equals [:relationship, :relationship_details, :related_resource_klass], source_join_options.keys
48+
49+
relationship_join_options = join_manager.join_details_by_relationship(PostResource._relationship(:tags))[:join_options]
50+
assert_array_equals [:relationship, :relationship_details, :related_resource_klass], relationship_join_options.keys
3751
end
3852

3953
def test_add_single_sort_join
@@ -43,8 +57,8 @@ def test_add_single_sort_join
4357
records = join_manager.join(records, {})
4458

4559
assert_equal 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "posts_tags" ON "posts_tags"."post_id" = "posts"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "posts_tags"."tag_id"', records.to_sql
46-
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details)
47-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)))
60+
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options))
61+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options))
4862
end
4963

5064
def test_add_single_sort_and_filter_join
@@ -54,8 +68,8 @@ def test_add_single_sort_and_filter_join
5468
records = PostResource.records({})
5569
records = join_manager.join(records, {})
5670
assert_equal 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "posts_tags" ON "posts_tags"."post_id" = "posts"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "posts_tags"."tag_id"', records.to_sql
57-
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details)
58-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)))
71+
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options))
72+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options))
5973
end
6074

6175
def test_add_sibling_joins
@@ -69,9 +83,9 @@ def test_add_sibling_joins
6983
records = join_manager.join(records, {})
7084

7185
assert_equal 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "posts_tags" ON "posts_tags"."post_id" = "posts"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "posts_tags"."tag_id" LEFT OUTER JOIN "people" ON "people"."id" = "posts"."author_id"', records.to_sql
72-
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details)
73-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)))
74-
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:author)))
86+
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options))
87+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options))
88+
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:author)).except!(:join_options))
7589
end
7690

7791

@@ -82,7 +96,7 @@ def test_add_joins_source_relationship
8296
records = join_manager.join(records, {})
8397

8498
assert_equal 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"', records.to_sql
85-
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details)
99+
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options))
86100
end
87101

88102

@@ -96,7 +110,7 @@ def test_add_joins_source_relationship_with_custom_apply
96110

97111
assert_equal sql, records.to_sql
98112

99-
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details)
113+
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options))
100114
end
101115

102116
def test_add_nested_scoped_joins
@@ -118,11 +132,11 @@ def test_add_nested_scoped_joins
118132

119133
assert_equal sql, records.to_sql
120134

121-
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details)
122-
assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)))
123-
assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)))
124-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)))
125-
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author)))
135+
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options))
136+
assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)).except!(:join_options))
137+
assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)).except!(:join_options))
138+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)).except!(:join_options))
139+
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author)).except!(:join_options))
126140

127141
# Now test with different order for the filters
128142
filters = {
@@ -144,11 +158,11 @@ def test_add_nested_scoped_joins
144158

145159
assert_equal sql, records.to_sql
146160

147-
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details)
148-
assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)))
149-
assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)))
150-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)))
151-
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author)))
161+
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options))
162+
assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)).except!(:join_options))
163+
assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)).except!(:join_options))
164+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)).except!(:join_options))
165+
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author)).except!(:join_options))
152166

153167
# Easier to read SQL to show joins are the same, but in different order
154168
# Pass 1
@@ -187,11 +201,11 @@ def test_add_nested_joins_with_fields
187201

188202
assert_equal sql, records.to_sql
189203

190-
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details)
191-
assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)))
192-
assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)))
193-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)))
194-
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author)))
204+
assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options))
205+
assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)).except!(:join_options))
206+
assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)).except!(:join_options))
207+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)).except!(:join_options))
208+
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author)).except!(:join_options))
195209
end
196210

197211
def test_add_joins_with_sub_relationship
@@ -233,11 +247,11 @@ def test_add_joins_with_sub_relationship_and_filters
233247
records = PostResource.records({})
234248
records = join_manager.join(records, {})
235249

236-
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details)
237-
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(PostResource._relationship(:comments)))
238-
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:author)))
239-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:tags)))
240-
assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(PersonResource._relationship(:comments)))
250+
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options))
251+
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(PostResource._relationship(:comments)).except!(:join_options))
252+
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:author)).except!(:join_options))
253+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:tags)).except!(:join_options))
254+
assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(PersonResource._relationship(:comments)).except!(:join_options))
241255
end
242256

243257
def test_polymorphic_join_belongs_to_just_source
@@ -248,10 +262,10 @@ def test_polymorphic_join_belongs_to_just_source
248262
records = join_manager.join(records, {})
249263

250264
# assert_equal 'SELECT "pictures".* FROM "pictures" LEFT OUTER JOIN "products" ON "products"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Product\' LEFT OUTER JOIN "documents" ON "documents"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Document\'', records.to_sql
251-
assert_hash_equals({alias: 'products', join_type: :left}, join_manager.source_join_details('products'))
252-
assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.source_join_details('documents'))
253-
assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products'))
254-
assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents'))
265+
assert_hash_equals({alias: 'products', join_type: :left}, join_manager.source_join_details('products').except!(:join_options))
266+
assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.source_join_details('documents').except!(:join_options))
267+
assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products').except!(:join_options))
268+
assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents').except!(:join_options))
255269
end
256270

257271
def test_polymorphic_join_belongs_to_filter
@@ -262,9 +276,9 @@ def test_polymorphic_join_belongs_to_filter
262276
records = join_manager.join(records, {})
263277

264278
# assert_equal 'SELECT "pictures".* FROM "pictures" LEFT OUTER JOIN "products" ON "products"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Product\' LEFT OUTER JOIN "documents" ON "documents"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Document\'', records.to_sql
265-
assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details)
266-
assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products'))
267-
assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents'))
279+
assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details.except!(:join_options))
280+
assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products').except!(:join_options))
281+
assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents').except!(:join_options))
268282
end
269283

270284
def test_polymorphic_join_belongs_to_filter_on_resource
@@ -285,9 +299,9 @@ def test_polymorphic_join_belongs_to_filter_on_resource
285299
sql_v2 = 'SELECT "pictures".* FROM "pictures" LEFT OUTER JOIN "documents" ON "documents"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Document\' LEFT OUTER JOIN "products" ON "products"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Product\' LEFT OUTER JOIN "file_properties" ON "file_properties"."fileable_type" = \'Picture\' AND "file_properties"."fileable_id" = "pictures"."id"'
286300
assert records.to_sql == sql_v1 || records.to_sql == sql_v2, 'did not generate an expected sql statement'
287301

288-
assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details)
289-
assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products'))
290-
assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents'))
291-
assert_hash_equals({alias: 'file_properties', join_type: :left}, join_manager.join_details_by_relationship(PictureResource._relationship(:file_properties)))
302+
assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details.except!(:join_options))
303+
assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products').except!(:join_options))
304+
assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents').except!(:join_options))
305+
assert_hash_equals({alias: 'file_properties', join_type: :left}, join_manager.join_details_by_relationship(PictureResource._relationship(:file_properties)).except!(:join_options))
292306
end
293307
end

0 commit comments

Comments
 (0)