Skip to content

Commit

Permalink
Merge records in apply_joins
Browse files Browse the repository at this point in the history
  • Loading branch information
lgebhardt committed Feb 9, 2020
1 parent ce3084e commit 54f6024
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 16 deletions.
7 changes: 7 additions & 0 deletions lib/jsonapi/active_relation_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ def apply_join(records:, relationship:, resource_type:, join_type:, options:)
when :left
records = records.joins_left(resource_type.to_s.singularize.to_sym)
end
records = records.merge(self.records(options))
else
relation_name = relationship.relation_name(options)
case join_type
Expand All @@ -323,6 +324,12 @@ def apply_join(records:, relationship:, resource_type:, join_type:, options:)
when :left
records = records.joins_left(relation_name)
end

# Merge in the default `records` if a custom relation isn't specified and skip
# when a custom relation_name is specified by the relationship
if relation_name == relationship.name.to_sym
records = records.merge(self.records(options))
end
end
records
end
Expand Down
24 changes: 8 additions & 16 deletions test/fixtures/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1932,16 +1932,7 @@ class AuthorResource < JSONAPI::Resource
model_name 'Person'
attributes :name

has_many :books, inverse_relationship: :authors, relation_name: -> (options) {
book_admin = options[:context][:book_admin] || options[:context][:current_user].try(:book_admin)

if book_admin
:books
else
:not_banned_books
end
}

has_many :books
has_many :book_comments
end

Expand Down Expand Up @@ -1981,6 +1972,9 @@ class BookResource < JSONAPI::Resource
}

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

class << self
def books
Expand All @@ -1992,10 +1986,9 @@ def not_banned_books
end

def records(options = {})
context = options[:context]
current_user = context ? context[:current_user] : nil
current_user = options.dig(:context, :current_user)

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

def apply_filter_banned(records, value, options)
context = options[:context]
current_user = context ? context[:current_user] : nil
current_user = options.dig(:context, :current_user)

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

def records(options = {})
current_user = options[:context][:current_user]
current_user = options.dig(:context, :current_user)
_model_class.for_user(current_user)
end
end
Expand Down
38 changes: 38 additions & 0 deletions test/integration/authorization.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require File.expand_path('../../test_helper', __FILE__)

class RequestTest < ActionDispatch::IntegrationTest
def setup
DatabaseCleaner.start
JSONAPI.configuration.json_key_format = :underscored_key
JSONAPI.configuration.route_format = :underscored_route
Api::V2::BookResource.paginator :offset
end

def test_restricted_records_primary
Api::V2::BookResource.paginator :none

# Not a book admin
$test_user = Person.find(1001)
assert_cacheable_jsonapi_get '/api/v2/books?filter[title]=Book%206'
assert_equal 12, json_response['data'].size

# book_admin
$test_user = Person.find(1005)
assert_cacheable_jsonapi_get '/api/v2/books?filter[title]=Book%206'
assert_equal 111, json_response['data'].size
end

def test_restricted_records_related
Api::V2::BookResource.paginator :none

# Not a book admin
$test_user = Person.find(1001)
assert_cacheable_jsonapi_get '/api/v2/authors/1002/books'
assert_equal 1, json_response['data'].size

# book_admin
$test_user = Person.find(1005)
assert_cacheable_jsonapi_get '/api/v2/authors/1002/books'
assert_equal 2, json_response['data'].size
end
end

0 comments on commit 54f6024

Please sign in to comment.