From 7202b7321e6444326c2937c155b3aa36c3ec9220 Mon Sep 17 00:00:00 2001 From: lgebhardt Date: Sat, 23 Sep 2023 10:29:57 -0400 Subject: [PATCH 1/5] Restore `use_related_resource_records_for_joins` for v0_10 --- lib/jsonapi/active_relation_retrieval_v10.rb | 7 ++++++- lib/jsonapi/configuration.rb | 10 +++++++++- lib/jsonapi/relationship.rb | 11 ++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/jsonapi/active_relation_retrieval_v10.rb b/lib/jsonapi/active_relation_retrieval_v10.rb index 5f051c8a..9464af76 100644 --- a/lib/jsonapi/active_relation_retrieval_v10.rb +++ b/lib/jsonapi/active_relation_retrieval_v10.rb @@ -101,7 +101,7 @@ def find_fragments(filters, options = {}) sort_criteria = options.fetch(:sort_criteria) { [] } - join_manager = ActiveRelation::JoinManager.new(resource_klass: resource_klass, + join_manager = ActiveRelation::JoinManagerV10.new(resource_klass: resource_klass, source_relationship: nil, relationships: linkage_relationships.collect(&:name), sort_criteria: sort_criteria, @@ -316,6 +316,11 @@ def apply_join(records:, relationship:, resource_type:, join_type:, options:) records = records.joins_left(relation_name) end end + + if relationship.use_related_resource_records_for_joins + records = records.merge(self.records(options)) + end + records end diff --git a/lib/jsonapi/configuration.rb b/lib/jsonapi/configuration.rb index c5dc723d..6d6c7850 100644 --- a/lib/jsonapi/configuration.rb +++ b/lib/jsonapi/configuration.rb @@ -42,7 +42,8 @@ class Configuration :resource_cache_digest_function, :resource_cache_usage_report_function, :default_exclude_links, - :default_resource_retrieval_strategy + :default_resource_retrieval_strategy, + :use_related_resource_records_for_joins def initialize #:underscored_key, :camelized_key, :dasherized_key, or custom @@ -176,6 +177,11 @@ def initialize # :none # :self self.default_resource_retrieval_strategy = 'JSONAPI::ActiveRelationRetrieval' + + # For 'JSONAPI::ActiveRelationRetrievalV10': use a related resource's `records` when performing joins. + # This setting allows included resources to account for permission scopes. It can be overridden explicitly per + # relationship. Furthermore, specifying a `relation_name` on a relationship will cause this setting to be ignored. + self.use_related_resource_records_for_joins = true end def cache_formatters=(bool) @@ -319,6 +325,8 @@ def allow_include=(allow_include) attr_writer :default_exclude_links attr_writer :default_resource_retrieval_strategy + + attr_writer :use_related_resource_records_for_joins end class << self diff --git a/lib/jsonapi/relationship.rb b/lib/jsonapi/relationship.rb index 2308b0a3..31a053b2 100644 --- a/lib/jsonapi/relationship.rb +++ b/lib/jsonapi/relationship.rb @@ -5,7 +5,7 @@ class Relationship attr_reader :acts_as_set, :foreign_key, :options, :name, :class_name, :polymorphic, :always_include_optional_linkage_data, :exclude_linkage_data, :parent_resource, :eager_load_on_include, :custom_methods, - :inverse_relationship, :allow_include, :hidden + :inverse_relationship, :allow_include, :hidden, :use_related_resource_records_for_joins attr_writer :allow_include @@ -25,6 +25,15 @@ def initialize(name, options = {}) @polymorphic_types ||= options[:polymorphic_relations] end + use_related_resource_records_for_joins_default = if options[:relation_name] + false + else + JSONAPI.configuration.use_related_resource_records_for_joins + end + + @use_related_resource_records_for_joins = options.fetch(:use_related_resource_records_for_joins, + use_related_resource_records_for_joins_default) == true + @hidden = options.fetch(:hidden, false) == true @exclude_linkage_data = options[:exclude_linkage_data] From 1366314dbc083a6805e2527c2e7cdfd7614d3a5a Mon Sep 17 00:00:00 2001 From: lgebhardt Date: Sun, 24 Sep 2023 11:08:48 -0400 Subject: [PATCH 2/5] Handle nil actual hashes --- test/helpers/assertions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers/assertions.rb b/test/helpers/assertions.rb index 42b28234..eee85efc 100644 --- a/test/helpers/assertions.rb +++ b/test/helpers/assertions.rb @@ -1,7 +1,7 @@ module Helpers module Assertions def assert_hash_equals(exp, act, msg = nil) - msg = message(msg, '') { diff exp.deep_stringify_keys, act.deep_stringify_keys } + msg = message(msg, '') { diff exp.deep_stringify_keys, act&.deep_stringify_keys } assert(matches_hash?(exp, act, {exact: true}), msg) end From 00e3c5fb6e0eb67ca1f6ca851d20094fdd3f461a Mon Sep 17 00:00:00 2001 From: lgebhardt Date: Sun, 24 Sep 2023 11:09:57 -0400 Subject: [PATCH 3/5] Add back join_options for v10 compatibility --- .../active_relation/join_manager_v10.rb | 10 +- .../join_manager_v10_test.rb | 126 ++++++++++-------- 2 files changed, 78 insertions(+), 58 deletions(-) diff --git a/lib/jsonapi/active_relation/join_manager_v10.rb b/lib/jsonapi/active_relation/join_manager_v10.rb index 5e1b8765..07ca0978 100644 --- a/lib/jsonapi/active_relation/join_manager_v10.rb +++ b/lib/jsonapi/active_relation/join_manager_v10.rb @@ -149,9 +149,15 @@ def perform_joins(records, options) related_resource_klass = join_details[:related_resource_klass] join_type = relationship_details[:join_type] + join_options = { + relationship: relationship, + relationship_details: relationship_details, + related_resource_klass: related_resource_klass, + } + if relationship == :root unless source_relationship - add_join_details('', {alias: resource_klass._table_name, join_type: :root}) + add_join_details('', {alias: resource_klass._table_name, join_type: :root, join_options: join_options}) end next end @@ -165,7 +171,7 @@ def perform_joins(records, options) options: options) } - details = {alias: self.class.alias_from_arel_node(join_node), join_type: join_type} + details = {alias: self.class.alias_from_arel_node(join_node), join_type: join_type, join_options: join_options} if relationship == source_relationship if relationship.polymorphic? && relationship.belongs_to? diff --git a/test/unit/active_relation_resource_finder/join_manager_v10_test.rb b/test/unit/active_relation_resource_finder/join_manager_v10_test.rb index bae45ecd..6a58891c 100644 --- a/test/unit/active_relation_resource_finder/join_manager_v10_test.rb +++ b/test/unit/active_relation_resource_finder/join_manager_v10_test.rb @@ -7,9 +7,9 @@ def test_no_added_joins records = PostResource.records({}) records = join_manager.join(records, {}) - assert_equal 'SELECT "posts".* FROM "posts"', sql_for_compare(records.to_sql) + assert_equal 'SELECT "posts".* FROM "posts"', records.to_sql - assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details) + assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) end def test_add_single_join @@ -17,9 +17,23 @@ def test_add_single_join join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, filters: filters) records = PostResource.records({}) records = join_manager.join(records, {}) - 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) - assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags))) + 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 + assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options)) + end + + def test_joins_have_join_options + filters = {'tags' => ['1']} + join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, filters: filters) + records = PostResource.records({}) + records = join_manager.join(records, {}) + 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 + + source_join_options = join_manager.source_join_details[:join_options] + assert_array_equals [:relationship, :relationship_details, :related_resource_klass], source_join_options.keys + + relationship_join_options = join_manager.join_details_by_relationship(PostResource._relationship(:tags))[:join_options] + assert_array_equals [:relationship, :relationship_details, :related_resource_klass], relationship_join_options.keys end def test_add_single_sort_join @@ -28,9 +42,9 @@ def test_add_single_sort_join records = PostResource.records({}) records = join_manager.join(records, {}) - 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) - assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags))) + 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 + assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options)) end def test_add_single_sort_and_filter_join @@ -39,9 +53,9 @@ def test_add_single_sort_and_filter_join join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, sort_criteria: sort_criteria, filters: filters) records = PostResource.records({}) records = join_manager.join(records, {}) - 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) - assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags))) + 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 + assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options)) end def test_add_sibling_joins @@ -54,10 +68,10 @@ def test_add_sibling_joins records = PostResource.records({}) records = join_manager.join(records, {}) - 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"', sql_for_compare(records.to_sql) - assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags))) - assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:author))) + 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 + assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options)) + assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:author)).except!(:join_options)) end @@ -67,8 +81,8 @@ def test_add_joins_source_relationship records = PostResource.records({}) records = join_manager.join(records, {}) - assert_equal 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"', sql_for_compare(records.to_sql) - assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details) + assert_equal 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"', records.to_sql + assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options)) end @@ -80,9 +94,9 @@ def test_add_joins_source_relationship_with_custom_apply sql = 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE "comments"."approved" = ' + db_true - assert_equal sql, sql_for_compare(records.to_sql) + assert_equal sql, records.to_sql - assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details) + assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options)) end def test_add_nested_scoped_joins @@ -96,11 +110,11 @@ def test_add_nested_scoped_joins records = Api::V10::PostResource.records({}) records = join_manager.join(records, {}) - assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details) - assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments))) - assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author))) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags))) - assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author))) + assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)).except!(:join_options)) + assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)).except!(:join_options)) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)).except!(:join_options)) + assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author)).except!(:join_options)) # Now test with different order for the filters filters = { @@ -113,11 +127,11 @@ def test_add_nested_scoped_joins records = Api::V10::PostResource.records({}) records = join_manager.join(records, {}) - assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details) - assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments))) - assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author))) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags))) - assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author))) + assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)).except!(:join_options)) + assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)).except!(:join_options)) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)).except!(:join_options)) + assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author)).except!(:join_options)) end def test_add_nested_joins_with_fields @@ -131,11 +145,11 @@ def test_add_nested_joins_with_fields records = Api::V10::PostResource.records({}) records = join_manager.join(records, {}) - assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details) - assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments))) - assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author))) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags))) - assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author))) + assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)).except!(:join_options)) + assert_hash_equals({alias: 'authors_comments', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)).except!(:join_options)) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)).except!(:join_options)) + assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:author)).except!(:join_options)) end def test_add_joins_with_sub_relationship @@ -146,10 +160,10 @@ def test_add_joins_with_sub_relationship records = Api::V10::PostResource.records({}) records = join_manager.join(records, {}) - assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details) - assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments))) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags))) - assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PersonResource._relationship(:comments))) + assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)).except!(:join_options)) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)).except!(:join_options)) + assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PersonResource._relationship(:comments)).except!(:join_options)) end def test_add_joins_with_sub_relationship_and_filters @@ -167,11 +181,11 @@ def test_add_joins_with_sub_relationship_and_filters records = PostResource.records({}) records = join_manager.join(records, {}) - assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details) - assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(PostResource._relationship(:comments))) - assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:author))) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:tags))) - assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(PersonResource._relationship(:comments))) + assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(PostResource._relationship(:comments)).except!(:join_options)) + assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:author)).except!(:join_options)) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:tags)).except!(:join_options)) + assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(PersonResource._relationship(:comments)).except!(:join_options)) end def test_polymorphic_join_belongs_to_just_source @@ -181,11 +195,11 @@ def test_polymorphic_join_belongs_to_just_source records = PictureResource.records({}) records = join_manager.join(records, {}) - # 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\'', sql_for_compare(records.to_sql) - assert_hash_equals({alias: 'products', join_type: :left}, join_manager.source_join_details('products')) - assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.source_join_details('documents')) - assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products')) - assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents')) + # 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 + assert_hash_equals({alias: 'products', join_type: :left}, join_manager.source_join_details('products').except!(:join_options)) + assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.source_join_details('documents').except!(:join_options)) + assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products').except!(:join_options)) + assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents').except!(:join_options)) end def test_polymorphic_join_belongs_to_filter @@ -195,10 +209,10 @@ def test_polymorphic_join_belongs_to_filter records = PictureResource.records({}) records = join_manager.join(records, {}) - # 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\'', sql_for_compare(records.to_sql) - assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details) - assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products')) - assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents')) + # 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 + assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products').except!(:join_options)) + assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents').except!(:join_options)) end def test_polymorphic_join_belongs_to_filter_on_resource @@ -214,9 +228,9 @@ def test_polymorphic_join_belongs_to_filter_on_resource records = PictureResource.records({}) records = join_manager.join(records, {}) - assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details) - assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products')) - assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents')) - assert_hash_equals({alias: 'file_properties', join_type: :left}, join_manager.join_details_by_relationship(PictureResource._relationship(:file_properties))) + assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details.except!(:join_options)) + assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products').except!(:join_options)) + assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents').except!(:join_options)) + assert_hash_equals({alias: 'file_properties', join_type: :left}, join_manager.join_details_by_relationship(PictureResource._relationship(:file_properties)).except!(:join_options)) end end From db5b70e7e0ae7bf3611ffce9eb034ce3c1f480a6 Mon Sep 17 00:00:00 2001 From: lgebhardt Date: Tue, 26 Sep 2023 09:23:57 -0400 Subject: [PATCH 4/5] Test JoinManager not JoinManagerV10 --- .../join_manager_test.rb | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test/unit/active_relation_resource_finder/join_manager_test.rb b/test/unit/active_relation_resource_finder/join_manager_test.rb index 5b46d345..53799e9e 100644 --- a/test/unit/active_relation_resource_finder/join_manager_test.rb +++ b/test/unit/active_relation_resource_finder/join_manager_test.rb @@ -11,7 +11,7 @@ class JoinManagerTest < ActiveSupport::TestCase # end def test_no_added_joins - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource) + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource) records = PostResource.records({}) records = join_manager.join(records, {}) @@ -22,7 +22,7 @@ def test_no_added_joins def test_add_single_join filters = {'tags' => ['1']} - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, filters: filters) + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, filters: filters) records = PostResource.records({}) records = join_manager.join(records, {}) 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 def test_add_single_sort_join sort_criteria = [{field: 'tags.name', direction: :desc}] - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, sort_criteria: sort_criteria) + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, sort_criteria: sort_criteria) records = PostResource.records({}) records = join_manager.join(records, {}) @@ -44,7 +44,7 @@ def test_add_single_sort_join def test_add_single_sort_and_filter_join filters = {'tags' => ['1']} sort_criteria = [{field: 'tags.name', direction: :desc}] - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, sort_criteria: sort_criteria, filters: filters) + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, sort_criteria: sort_criteria, filters: filters) records = PostResource.records({}) records = join_manager.join(records, {}) 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 'author' => ['1'] } - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, filters: filters) + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, filters: filters) records = PostResource.records({}) records = join_manager.join(records, {}) @@ -70,7 +70,7 @@ def test_add_sibling_joins def test_add_joins_source_relationship - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, source_relationship: PostResource._relationship(:comments)) records = PostResource.records({}) records = join_manager.join(records, {}) @@ -81,7 +81,7 @@ def test_add_joins_source_relationship def test_add_joins_source_relationship_with_custom_apply - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource, + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource, source_relationship: Api::V10::PostResource._relationship(:comments)) records = Api::V10::PostResource.records({}) records = join_manager.join(records, {}) @@ -100,7 +100,7 @@ def test_add_nested_scoped_joins 'author' => ['1'] } - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource, filters: filters) + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource, filters: filters) records = Api::V10::PostResource.records({}) records = join_manager.join(records, {}) @@ -117,7 +117,7 @@ def test_add_nested_scoped_joins 'comments.tags' => ['1'] } - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource, filters: filters) + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource, filters: filters) records = Api::V10::PostResource.records({}) records = join_manager.join(records, {}) @@ -135,7 +135,7 @@ def test_add_nested_joins_with_fields 'author.foo' => ['1'] } - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource, filters: filters) + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource, filters: filters) records = Api::V10::PostResource.records({}) records = join_manager.join(records, {}) @@ -149,14 +149,14 @@ def test_add_nested_joins_with_fields def test_add_joins_with_sub_relationship relationships = %w(author author.comments tags) - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: Api::V10::PostResource, relationships: relationships, + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: Api::V10::PostResource, relationships: relationships, source_relationship: Api::V10::PostResource._relationship(:comments)) records = Api::V10::PostResource.records({}) records = join_manager.join(records, {}) assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details) assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments))) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags))) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:tags))) assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PersonResource._relationship(:comments))) end @@ -168,7 +168,7 @@ def test_add_joins_with_sub_relationship_and_filters relationships = %w(author author.comments tags) - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PostResource, filters: filters, relationships: relationships, source_relationship: PostResource._relationship(:comments)) @@ -177,13 +177,13 @@ def test_add_joins_with_sub_relationship_and_filters assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details) assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(PostResource._relationship(:comments))) - assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:author))) - assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(CommentResource._relationship(:tags))) + assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:author))) + assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags))) assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(PersonResource._relationship(:comments))) end def test_polymorphic_join_belongs_to_just_source - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new( + join_manager = JSONAPI::ActiveRelation::JoinManager.new( resource_klass: PictureResource, source_relationship: PictureResource._relationship(:imageable) ) @@ -200,7 +200,7 @@ def test_polymorphic_join_belongs_to_just_source def test_polymorphic_join_belongs_to_filter filters = {'imageable' => ['Foo']} - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PictureResource, filters: filters) + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PictureResource, filters: filters) records = PictureResource.records({}) records = join_manager.join(records, {}) @@ -217,7 +217,7 @@ def test_polymorphic_join_belongs_to_filter_on_resource } relationships = %w(imageable file_properties) - join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PictureResource, + join_manager = JSONAPI::ActiveRelation::JoinManager.new(resource_klass: PictureResource, filters: filters, relationships: relationships) From f30d6b4761a8f07e478e3a0d6772dd73d588745b Mon Sep 17 00:00:00 2001 From: lgebhardt Date: Tue, 26 Sep 2023 09:30:25 -0400 Subject: [PATCH 5/5] Use sql_for_compare to account for different sql dialect quoating --- .../join_manager_v10_test.rb | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/unit/active_relation_resource_finder/join_manager_v10_test.rb b/test/unit/active_relation_resource_finder/join_manager_v10_test.rb index 6a58891c..d0ec9a29 100644 --- a/test/unit/active_relation_resource_finder/join_manager_v10_test.rb +++ b/test/unit/active_relation_resource_finder/join_manager_v10_test.rb @@ -7,7 +7,7 @@ def test_no_added_joins records = PostResource.records({}) records = join_manager.join(records, {}) - assert_equal 'SELECT "posts".* FROM "posts"', records.to_sql + assert_equal 'SELECT "posts".* FROM "posts"', sql_for_compare(records.to_sql) assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) end @@ -17,7 +17,7 @@ def test_add_single_join join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, filters: filters) records = PostResource.records({}) records = join_manager.join(records, {}) - 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 + 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) assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options)) end @@ -27,7 +27,7 @@ def test_joins_have_join_options join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, filters: filters) records = PostResource.records({}) records = join_manager.join(records, {}) - 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 + 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) source_join_options = join_manager.source_join_details[:join_options] assert_array_equals [:relationship, :relationship_details, :related_resource_klass], source_join_options.keys @@ -42,7 +42,7 @@ def test_add_single_sort_join records = PostResource.records({}) records = join_manager.join(records, {}) - 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 + 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) assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options)) end @@ -53,7 +53,7 @@ def test_add_single_sort_and_filter_join join_manager = JSONAPI::ActiveRelation::JoinManagerV10.new(resource_klass: PostResource, sort_criteria: sort_criteria, filters: filters) records = PostResource.records({}) records = join_manager.join(records, {}) - 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 + 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) assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options)) end @@ -68,7 +68,7 @@ def test_add_sibling_joins records = PostResource.records({}) records = join_manager.join(records, {}) - 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 + 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"', sql_for_compare(records.to_sql) assert_hash_equals({alias: 'posts', join_type: :root}, join_manager.source_join_details.except!(:join_options)) assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:tags)).except!(:join_options)) assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(PostResource._relationship(:author)).except!(:join_options)) @@ -81,7 +81,7 @@ def test_add_joins_source_relationship records = PostResource.records({}) records = join_manager.join(records, {}) - assert_equal 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"', records.to_sql + assert_equal 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"', sql_for_compare(records.to_sql) assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options)) end @@ -94,7 +94,7 @@ def test_add_joins_source_relationship_with_custom_apply sql = 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE "comments"."approved" = ' + db_true - assert_equal sql, records.to_sql + assert_equal sql, sql_for_compare(records.to_sql) assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options)) end @@ -195,7 +195,7 @@ def test_polymorphic_join_belongs_to_just_source records = PictureResource.records({}) records = join_manager.join(records, {}) - # 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 + # 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\'', sql_for_compare(records.to_sql) assert_hash_equals({alias: 'products', join_type: :left}, join_manager.source_join_details('products').except!(:join_options)) assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.source_join_details('documents').except!(:join_options)) assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products').except!(:join_options)) @@ -209,7 +209,7 @@ def test_polymorphic_join_belongs_to_filter records = PictureResource.records({}) records = join_manager.join(records, {}) - # 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 + # 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\'', sql_for_compare(records.to_sql) assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details.except!(:join_options)) assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products').except!(:join_options)) assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents').except!(:join_options))