Skip to content

Commit 125cef4

Browse files
committed
Restore use_related_resource_records_for_joins for v0_10 (#1412)
* Restore `use_related_resource_records_for_joins` for v0_10 * Handle nil actual hashes * Add back join_options for v10 compatibility * Test JoinManager not JoinManagerV10 * Use sql_for_compare to account for different sql dialect quoating
1 parent 2dd0589 commit 125cef4

File tree

7 files changed

+113
-71
lines changed

7 files changed

+113
-71
lines changed

lib/jsonapi/active_relation/join_manager_v10.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,15 @@ def perform_joins(records, options)
149149
related_resource_klass = join_details[:related_resource_klass]
150150
join_type = relationship_details[:join_type]
151151

152+
join_options = {
153+
relationship: relationship,
154+
relationship_details: relationship_details,
155+
related_resource_klass: related_resource_klass,
156+
}
157+
152158
if relationship == :root
153159
unless source_relationship
154-
add_join_details('', {alias: resource_klass._table_name, join_type: :root})
160+
add_join_details('', {alias: resource_klass._table_name, join_type: :root, join_options: join_options})
155161
end
156162
next
157163
end
@@ -165,7 +171,7 @@ def perform_joins(records, options)
165171
options: options)
166172
}
167173

168-
details = {alias: self.class.alias_from_arel_node(join_node), join_type: join_type}
174+
details = {alias: self.class.alias_from_arel_node(join_node), join_type: join_type, join_options: join_options}
169175

170176
if relationship == source_relationship
171177
if relationship.polymorphic? && relationship.belongs_to?

lib/jsonapi/active_relation_retrieval_v10.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def find_fragments(filters, options = {})
101101

102102
sort_criteria = options.fetch(:sort_criteria) { [] }
103103

104-
join_manager = ActiveRelation::JoinManager.new(resource_klass: resource_klass,
104+
join_manager = ActiveRelation::JoinManagerV10.new(resource_klass: resource_klass,
105105
source_relationship: nil,
106106
relationships: linkage_relationships.collect(&:name),
107107
sort_criteria: sort_criteria,
@@ -316,6 +316,11 @@ def apply_join(records:, relationship:, resource_type:, join_type:, options:)
316316
records = records.joins_left(relation_name)
317317
end
318318
end
319+
320+
if relationship.use_related_resource_records_for_joins
321+
records = records.merge(self.records(options))
322+
end
323+
319324
records
320325
end
321326

lib/jsonapi/configuration.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ class Configuration
4242
:resource_cache_digest_function,
4343
:resource_cache_usage_report_function,
4444
:default_exclude_links,
45-
:default_resource_retrieval_strategy
45+
:default_resource_retrieval_strategy,
46+
:use_related_resource_records_for_joins
4647

4748
def initialize
4849
#:underscored_key, :camelized_key, :dasherized_key, or custom
@@ -176,6 +177,11 @@ def initialize
176177
# :none
177178
# :self
178179
self.default_resource_retrieval_strategy = 'JSONAPI::ActiveRelationRetrieval'
180+
181+
# For 'JSONAPI::ActiveRelationRetrievalV10': use a related resource's `records` when performing joins.
182+
# This setting allows included resources to account for permission scopes. It can be overridden explicitly per
183+
# relationship. Furthermore, specifying a `relation_name` on a relationship will cause this setting to be ignored.
184+
self.use_related_resource_records_for_joins = true
179185
end
180186

181187
def cache_formatters=(bool)
@@ -319,6 +325,8 @@ def allow_include=(allow_include)
319325
attr_writer :default_exclude_links
320326

321327
attr_writer :default_resource_retrieval_strategy
328+
329+
attr_writer :use_related_resource_records_for_joins
322330
end
323331

324332
class << self

lib/jsonapi/relationship.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class Relationship
55
attr_reader :acts_as_set, :foreign_key, :options, :name,
66
:class_name, :polymorphic, :always_include_optional_linkage_data, :exclude_linkage_data,
77
:parent_resource, :eager_load_on_include, :custom_methods,
8-
:inverse_relationship, :allow_include, :hidden
8+
:inverse_relationship, :allow_include, :hidden, :use_related_resource_records_for_joins
99

1010
attr_writer :allow_include
1111

@@ -25,6 +25,15 @@ def initialize(name, options = {})
2525
@polymorphic_types ||= options[:polymorphic_relations]
2626
end
2727

28+
use_related_resource_records_for_joins_default = if options[:relation_name]
29+
false
30+
else
31+
JSONAPI.configuration.use_related_resource_records_for_joins
32+
end
33+
34+
@use_related_resource_records_for_joins = options.fetch(:use_related_resource_records_for_joins,
35+
use_related_resource_records_for_joins_default) == true
36+
2837
@hidden = options.fetch(:hidden, false) == true
2938

3039
@exclude_linkage_data = options[:exclude_linkage_data]

test/helpers/assertions.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Helpers
22
module Assertions
33
def assert_hash_equals(exp, act, msg = nil)
4-
msg = message(msg, '') { diff exp.deep_stringify_keys, act.deep_stringify_keys }
4+
msg = message(msg, '') { diff exp.deep_stringify_keys, act&.deep_stringify_keys }
55
assert(matches_hash?(exp, act, {exact: true}), msg)
66
end
77

test/unit/active_relation_resource_finder/join_manager_test.rb

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class JoinManagerTest < ActiveSupport::TestCase
1111
# end
1212

1313
def test_no_added_joins
14-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource)
14+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource)
1515

1616
records = PostResource.records({})
1717
records = join_manager.join(records, {})
@@ -22,7 +22,7 @@ def test_no_added_joins
2222

2323
def test_add_single_join
2424
filters = {'tags' => ['1']}
25-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, filters: filters)
25+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, filters: filters)
2626
records = PostResource.records({})
2727
records = join_manager.join(records, {})
2828
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"', sql_for_compare(records.to_sql)
@@ -32,7 +32,7 @@ def test_add_single_join
3232

3333
def test_add_single_sort_join
3434
sort_criteria = [{field: 'tags.name', direction: :desc}]
35-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, sort_criteria: sort_criteria)
35+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, sort_criteria: sort_criteria)
3636
records = PostResource.records({})
3737
records = join_manager.join(records, {})
3838

@@ -44,7 +44,7 @@ def test_add_single_sort_join
4444
def test_add_single_sort_and_filter_join
4545
filters = {'tags' => ['1']}
4646
sort_criteria = [{field: 'tags.name', direction: :desc}]
47-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, sort_criteria: sort_criteria, filters: filters)
47+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, sort_criteria: sort_criteria, filters: filters)
4848
records = PostResource.records({})
4949
records = join_manager.join(records, {})
5050
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"', sql_for_compare(records.to_sql)
@@ -58,7 +58,7 @@ def test_add_sibling_joins
5858
'author' => ['1']
5959
}
6060

61-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, filters: filters)
61+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, filters: filters)
6262
records = PostResource.records({})
6363
records = join_manager.join(records, {})
6464

@@ -70,7 +70,7 @@ def test_add_sibling_joins
7070

7171

7272
def test_add_joins_source_relationship
73-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource,
73+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource,
7474
source_relationship: PostResource._relationship(:comments))
7575
records = PostResource.records({})
7676
records = join_manager.join(records, {})
@@ -81,7 +81,7 @@ def test_add_joins_source_relationship
8181

8282

8383
def test_add_joins_source_relationship_with_custom_apply
84-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource,
84+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource,
8585
source_relationship: Api::V10::PostResource._relationship(:comments))
8686
records = Api::V10::PostResource.records({})
8787
records = join_manager.join(records, {})
@@ -100,7 +100,7 @@ def test_add_nested_scoped_joins
100100
'author' => ['1']
101101
}
102102

103-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource, filters: filters)
103+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource, filters: filters)
104104
records = Api::V10::PostResource.records({})
105105
records = join_manager.join(records, {})
106106

@@ -117,7 +117,7 @@ def test_add_nested_scoped_joins
117117
'comments.tags' => ['1']
118118
}
119119

120-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource, filters: filters)
120+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource, filters: filters)
121121
records = Api::V10::PostResource.records({})
122122
records = join_manager.join(records, {})
123123

@@ -135,7 +135,7 @@ def test_add_nested_joins_with_fields
135135
'author.foo' => ['1']
136136
}
137137

138-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource, filters: filters)
138+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource, filters: filters)
139139
records = Api::V10::PostResource.records({})
140140
records = join_manager.join(records, {})
141141

@@ -149,14 +149,14 @@ def test_add_nested_joins_with_fields
149149
def test_add_joins_with_sub_relationship
150150
relationships = %w(author author.comments tags)
151151

152-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource, relationships: relationships,
152+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource, relationships: relationships,
153153
source_relationship: Api::V10::PostResource._relationship(:comments))
154154
records = Api::V10::PostResource.records({})
155155
records = join_manager.join(records, {})
156156

157157
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details)
158158
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)))
159-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)))
159+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:tags)))
160160
assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PersonResource._relationship(:comments)))
161161
end
162162

@@ -168,7 +168,7 @@ def test_add_joins_with_sub_relationship_and_filters
168168

169169
relationships = %w(author author.comments tags)
170170

171-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource,
171+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource,
172172
filters: filters,
173173
relationships: relationships,
174174
source_relationship: PostResource._relationship(:comments))
@@ -177,13 +177,13 @@ def test_add_joins_with_sub_relationship_and_filters
177177

178178
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details)
179179
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(PostResource._relationship(:comments)))
180-
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:author)))
181-
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:tags)))
180+
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:author)))
181+
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)))
182182
assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(PersonResource._relationship(:comments)))
183183
end
184184

185185
def test_polymorphic_join_belongs_to_just_source
186-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(
186+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(
187187
resource_klass: PictureResource,
188188
source_relationship: PictureResource._relationship(:imageable)
189189
)
@@ -200,7 +200,7 @@ def test_polymorphic_join_belongs_to_just_source
200200

201201
def test_polymorphic_join_belongs_to_filter
202202
filters = {'imageable' => ['Foo']}
203-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PictureResource, filters: filters)
203+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PictureResource, filters: filters)
204204

205205
records = PictureResource.records({})
206206
records = join_manager.join(records, {})
@@ -217,7 +217,7 @@ def test_polymorphic_join_belongs_to_filter_on_resource
217217
}
218218

219219
relationships = %w(imageable file_properties)
220-
join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PictureResource,
220+
join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PictureResource,
221221
filters: filters,
222222
relationships: relationships)
223223

0 commit comments

Comments
 (0)