Skip to content

Commit 54f6024

Browse files
committed
Merge records in apply_joins
1 parent ce3084e commit 54f6024

File tree

3 files changed

+53
-16
lines changed

3 files changed

+53
-16
lines changed

lib/jsonapi/active_relation_resource.rb

+7
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ def apply_join(records:, relationship:, resource_type:, join_type:, options:)
315315
when :left
316316
records = records.joins_left(resource_type.to_s.singularize.to_sym)
317317
end
318+
records = records.merge(self.records(options))
318319
else
319320
relation_name = relationship.relation_name(options)
320321
case join_type
@@ -323,6 +324,12 @@ def apply_join(records:, relationship:, resource_type:, join_type:, options:)
323324
when :left
324325
records = records.joins_left(relation_name)
325326
end
327+
328+
# Merge in the default `records` if a custom relation isn't specified and skip
329+
# when a custom relation_name is specified by the relationship
330+
if relation_name == relationship.name.to_sym
331+
records = records.merge(self.records(options))
332+
end
326333
end
327334
records
328335
end

test/fixtures/active_record.rb

+8-16
Original file line numberDiff line numberDiff line change
@@ -1932,16 +1932,7 @@ class AuthorResource < JSONAPI::Resource
19321932
model_name 'Person'
19331933
attributes :name
19341934

1935-
has_many :books, inverse_relationship: :authors, relation_name: -> (options) {
1936-
book_admin = options[:context][:book_admin] || options[:context][:current_user].try(:book_admin)
1937-
1938-
if book_admin
1939-
:books
1940-
else
1941-
:not_banned_books
1942-
end
1943-
}
1944-
1935+
has_many :books
19451936
has_many :book_comments
19461937
end
19471938

@@ -1981,6 +1972,9 @@ class BookResource < JSONAPI::Resource
19811972
}
19821973

19831974
filter :banned, apply: :apply_filter_banned
1975+
filter :title, apply: ->(records, value, options) {
1976+
records.where('books.title LIKE ?', "#{value[0]}%")
1977+
}
19841978

19851979
class << self
19861980
def books
@@ -1992,10 +1986,9 @@ def not_banned_books
19921986
end
19931987

19941988
def records(options = {})
1995-
context = options[:context]
1996-
current_user = context ? context[:current_user] : nil
1989+
current_user = options.dig(:context, :current_user)
19971990

1998-
records = _model_class.all
1991+
records = super
19991992
# Hide the banned books from people who are not book admins
20001993
unless current_user && current_user.book_admin
20011994
records = records.where(not_banned_books)
@@ -2004,8 +1997,7 @@ def records(options = {})
20041997
end
20051998

20061999
def apply_filter_banned(records, value, options)
2007-
context = options[:context]
2008-
current_user = context ? context[:current_user] : nil
2000+
current_user = options.dig(:context, :current_user)
20092001

20102002
# Only book admins might filter for banned books
20112003
if current_user && current_user.book_admin
@@ -2045,7 +2037,7 @@ def approved_comments(approved = true)
20452037
end
20462038

20472039
def records(options = {})
2048-
current_user = options[:context][:current_user]
2040+
current_user = options.dig(:context, :current_user)
20492041
_model_class.for_user(current_user)
20502042
end
20512043
end

test/integration/authorization.rb

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
require File.expand_path('../../test_helper', __FILE__)
2+
3+
class RequestTest < ActionDispatch::IntegrationTest
4+
def setup
5+
DatabaseCleaner.start
6+
JSONAPI.configuration.json_key_format = :underscored_key
7+
JSONAPI.configuration.route_format = :underscored_route
8+
Api::V2::BookResource.paginator :offset
9+
end
10+
11+
def test_restricted_records_primary
12+
Api::V2::BookResource.paginator :none
13+
14+
# Not a book admin
15+
$test_user = Person.find(1001)
16+
assert_cacheable_jsonapi_get '/api/v2/books?filter[title]=Book%206'
17+
assert_equal 12, json_response['data'].size
18+
19+
# book_admin
20+
$test_user = Person.find(1005)
21+
assert_cacheable_jsonapi_get '/api/v2/books?filter[title]=Book%206'
22+
assert_equal 111, json_response['data'].size
23+
end
24+
25+
def test_restricted_records_related
26+
Api::V2::BookResource.paginator :none
27+
28+
# Not a book admin
29+
$test_user = Person.find(1001)
30+
assert_cacheable_jsonapi_get '/api/v2/authors/1002/books'
31+
assert_equal 1, json_response['data'].size
32+
33+
# book_admin
34+
$test_user = Person.find(1005)
35+
assert_cacheable_jsonapi_get '/api/v2/authors/1002/books'
36+
assert_equal 2, json_response['data'].size
37+
end
38+
end

0 commit comments

Comments
 (0)