Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use records for joined resource Classes #1307

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add tracking of join options for jsonapi-authorization gem
lgebhardt committed Feb 4, 2022
commit fc9053a6cc35fdc8c392fcca02c0237b3b141be3
10 changes: 8 additions & 2 deletions lib/jsonapi/active_relation/join_manager.rb
Original file line number Diff line number Diff line change
@@ -147,9 +147,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
@@ -163,7 +169,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?
108 changes: 61 additions & 47 deletions test/unit/active_relation_resource_finder/join_manager_test.rb
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ def test_no_added_joins
records = join_manager.join(records, {})
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
@@ -32,8 +32,22 @@ def test_add_single_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_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: '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::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"', 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
@@ -43,8 +57,8 @@ def test_add_single_sort_join
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_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: '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
@@ -54,8 +68,8 @@ def test_add_single_sort_and_filter_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_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: '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
@@ -69,9 +83,9 @@ def test_add_sibling_joins
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_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_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


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

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)
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details.except!(:join_options))
end


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

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
@@ -110,11 +124,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 = {
@@ -127,11 +141,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
@@ -145,11 +159,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
@@ -160,10 +174,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
@@ -181,11 +195,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
@@ -196,10 +210,10 @@ def test_polymorphic_join_belongs_to_just_source
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_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_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
@@ -210,9 +224,9 @@ def test_polymorphic_join_belongs_to_filter
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_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: '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
@@ -228,9 +242,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