Skip to content

Commit e17fcc2

Browse files
committed
Refactor ActiveRelationResourceFinder into ActiveRelationResource
Make Resource derive from ActiveRelationResource Support concept of `root_resource` for when we need to walk back up the resource ancestor chain since there can now be more than one root resource class (not just `JSONAPI::Resource`).
1 parent 9f7243e commit e17fcc2

File tree

12 files changed

+82
-82
lines changed

12 files changed

+82
-82
lines changed

lib/jsonapi-resources.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
require 'jsonapi/resources/railtie'
22
require 'jsonapi/naive_cache'
33
require 'jsonapi/compiled_json'
4+
require 'jsonapi/basic_resource'
5+
require 'jsonapi/active_relation_resource'
46
require 'jsonapi/resource'
57
require 'jsonapi/cached_response_fragment'
68
require 'jsonapi/response_document'
@@ -25,8 +27,8 @@
2527
require 'jsonapi/operation_result'
2628
require 'jsonapi/callbacks'
2729
require 'jsonapi/link_builder'
28-
require 'jsonapi/active_relation_resource_finder'
29-
require 'jsonapi/active_relation_resource_finder/join_manager'
30+
require 'jsonapi/active_relation/adapters/join_left_active_record_adapter'
31+
require 'jsonapi/active_relation/join_manager'
3032
require 'jsonapi/resource_identity'
3133
require 'jsonapi/resource_fragment'
3234
require 'jsonapi/resource_id_tree'
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module JSONAPI
2-
module ActiveRelationResourceFinder
2+
module ActiveRelation
33
module Adapters
44
module JoinLeftActiveRecordAdapter
55

lib/jsonapi/active_relation_resource_finder/join_manager.rb renamed to lib/jsonapi/active_relation/join_manager.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module JSONAPI
2-
module ActiveRelationResourceFinder
2+
module ActiveRelation
33

44
# Stores relationship paths starting from the resource_klass, consolidating duplicate paths from
55
# relationships, filters and sorts. When joins are made the table aliases are tracked in join_details

lib/jsonapi/active_relation_resource_finder.rb renamed to lib/jsonapi/active_relation_resource.rb

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
require 'jsonapi/active_relation_resource_finder/adapters/join_left_active_record_adapter'
2-
31
module JSONAPI
4-
module ActiveRelationResourceFinder
5-
def self.included(base)
6-
base.extend ClassMethods
7-
end
8-
9-
module ClassMethods
2+
class ActiveRelationResource < BasicResource
3+
root_resource
104

5+
class << self
116
# Finds Resources using the `filters`. Pagination and sort options are used when provided
127
#
138
# @param filters [Hash] the filters hash
@@ -19,9 +14,9 @@ module ClassMethods
1914
def find(filters, options = {})
2015
sort_criteria = options.fetch(:sort_criteria) { [] }
2116

22-
join_manager = JoinManager.new(resource_klass: self,
23-
filters: filters,
24-
sort_criteria: sort_criteria)
17+
join_manager = ActiveRelation::JoinManager.new(resource_klass: self,
18+
filters: filters,
19+
sort_criteria: sort_criteria)
2520

2621
paginator = options[:paginator]
2722

@@ -41,8 +36,8 @@ def find(filters, options = {})
4136
#
4237
# @return [Integer] the count
4338
def count(filters, options = {})
44-
join_manager = JoinManager.new(resource_klass: self,
45-
filters: filters)
39+
join_manager = ActiveRelation::JoinManager.new(resource_klass: self,
40+
filters: filters)
4641

4742
records = apply_request_settings_to_records(records: records(options),
4843
filters: filters,
@@ -101,11 +96,11 @@ def find_fragments(filters, options = {})
10196

10297
sort_criteria = options.fetch(:sort_criteria) { [] }
10398

104-
join_manager = JoinManager.new(resource_klass: resource_klass,
105-
source_relationship: nil,
106-
relationships: linkage_relationships,
107-
sort_criteria: sort_criteria,
108-
filters: filters)
99+
join_manager = ActiveRelation::JoinManager.new(resource_klass: resource_klass,
100+
source_relationship: nil,
101+
relationships: linkage_relationships,
102+
sort_criteria: sort_criteria,
103+
filters: filters)
109104

110105
paginator = options[:paginator]
111106

@@ -234,9 +229,9 @@ def count_related(source_rid, relationship_name, options = {})
234229
filters = options.fetch(:filters, {})
235230

236231
# Joins in this case are related to the related_klass
237-
join_manager = JoinManager.new(resource_klass: self,
238-
source_relationship: relationship,
239-
filters: filters)
232+
join_manager = ActiveRelation::JoinManager.new(resource_klass: self,
233+
source_relationship: relationship,
234+
filters: filters)
240235

241236
records = apply_request_settings_to_records(records: records(options),
242237
resource_klass: related_klass,
@@ -252,7 +247,7 @@ def count_related(source_rid, relationship_name, options = {})
252247
count_records(records)
253248
end
254249

255-
# This resource finder (ActiveRecordResourceFinder) uses an `ActiveRecord::Relation` as the starting point for
250+
# This resource class (ActiveRelationResource) uses an `ActiveRecord::Relation` as the starting point for
256251
# retrieving models. From this relation filters, sorts and joins are applied as needed.
257252
# Depending on which phase of the request processing different `records` methods will be called, giving the user
258253
# the opportunity to override them differently for performance and security reasons.
@@ -385,11 +380,11 @@ def find_related_monomorphic_fragments(source_rids, relationship, options, conne
385380
sort_criteria << { field: field, direction: sort[:direction] }
386381
end
387382

388-
join_manager = JoinManager.new(resource_klass: self,
389-
source_relationship: relationship,
390-
relationships: linkage_relationships,
391-
sort_criteria: sort_criteria,
392-
filters: filters)
383+
join_manager = ActiveRelation::JoinManager.new(resource_klass: self,
384+
source_relationship: relationship,
385+
relationships: linkage_relationships,
386+
sort_criteria: sort_criteria,
387+
filters: filters)
393388

394389
paginator = options[:paginator] if source_rids.count == 1
395390

@@ -511,10 +506,10 @@ def find_related_polymorphic_fragments(source_rids, relationship, options, conne
511506
end
512507
end
513508

514-
join_manager = JoinManager.new(resource_klass: self,
515-
source_relationship: relationship,
516-
relationships: linkage_relationships,
517-
filters: filters)
509+
join_manager = ActiveRelation::JoinManager.new(resource_klass: self,
510+
source_relationship: relationship,
511+
relationships: linkage_relationships,
512+
filters: filters)
518513

519514
paginator = options[:paginator] if source_rids.count == 1
520515

@@ -672,14 +667,14 @@ def find_related_polymorphic_fragments(source_rids, relationship, options, conne
672667
end
673668

674669
def apply_request_settings_to_records(records:,
675-
join_manager: JoinManager.new(resource_klass: self),
676-
resource_klass: self,
677-
filters: {},
678-
primary_keys: nil,
679-
sort_criteria: nil,
680-
sort_primary: nil,
681-
paginator: nil,
682-
options: {})
670+
join_manager: ActiveRelation::JoinManager.new(resource_klass: self),
671+
resource_klass: self,
672+
filters: {},
673+
primary_keys: nil,
674+
sort_criteria: nil,
675+
sort_primary: nil,
676+
paginator: nil,
677+
options: {})
683678

684679
opts = options.dup
685680
records = resource_klass.apply_joins(records, join_manager, opts)

lib/jsonapi/basic_resource.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ module JSONAPI
55
class BasicResource
66
include Callbacks
77

8+
@abstract = true
9+
@immutable = true
10+
@root = true
11+
812
attr_reader :context
913

1014
define_jsonapi_resources_callbacks :create,
@@ -893,6 +897,16 @@ def _polymorphic_resource_klasses
893897
end
894898
end
895899

900+
def root_resource
901+
@abstract = true
902+
@immutable = true
903+
@root = true
904+
end
905+
906+
def root?
907+
@root
908+
end
909+
896910
def abstract(val = true)
897911
@abstract = val
898912
end

lib/jsonapi/configuration.rb

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
require 'jsonapi/formatter'
22
require 'jsonapi/processor'
3-
require 'jsonapi/active_relation_resource_finder'
43
require 'concurrent'
54

65
module JSONAPI
@@ -17,7 +16,6 @@ class Configuration
1716
:default_paginator,
1817
:default_page_size,
1918
:maximum_page_size,
20-
:default_resource_finder,
2119
:default_processor_klass,
2220
:use_text_errors,
2321
:top_level_links_include_pagination,
@@ -105,12 +103,6 @@ def initialize
105103
self.always_include_to_one_linkage_data = false
106104
self.always_include_to_many_linkage_data = false
107105

108-
# ResourceFinder Mixin
109-
# The default ResourceFinder is the ActiveRelationResourceFinder which provides
110-
# access to ActiveRelation backed models. Custom ResourceFinders can be specified
111-
# in order to support other ORMs.
112-
self.default_resource_finder = JSONAPI::ActiveRelationResourceFinder
113-
114106
# The default Operation Processor to use if one is not defined specifically
115107
# for a Resource.
116108
self.default_processor_klass = JSONAPI::Processor
@@ -225,10 +217,6 @@ def default_processor_klass=(default_processor_klass)
225217
@default_processor_klass = default_processor_klass
226218
end
227219

228-
def default_resource_finder=(default_resource_finder)
229-
@default_resource_finder = default_resource_finder
230-
end
231-
232220
def allow_include=(allow_include)
233221
ActiveSupport::Deprecation.warn('`allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options.')
234222
@default_allow_include_to_one = allow_include

lib/jsonapi/relationship.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def initialize(name, options = {})
2727
@class_name = nil
2828
@inverse_relationship = nil
2929

30-
# Custom methods are reserved for use in resource finders. Not used in the default ActiveRelationResourceFinder
30+
# Custom methods are reserved for future use
3131
@custom_methods = options.fetch(:custom_methods, {})
3232
end
3333

lib/jsonapi/resource.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module JSONAPI
2+
class Resource < ActiveRelationResource
3+
root_resource
4+
end
5+
end

lib/jsonapi/resource_serializer.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def supplying_attribute_fields(resource_klass)
199199
@_supplying_attribute_fields.fetch resource_klass do
200200
attrs = Set.new(resource_klass._attributes.keys.map(&:to_sym))
201201
cur = resource_klass
202-
while cur != JSONAPI::Resource
202+
while !cur.root? # do not traverse beyond the first root resource
203203
if @fields.has_key?(cur._type)
204204
attrs &= @fields[cur._type]
205205
break
@@ -214,7 +214,7 @@ def supplying_relationship_fields(resource_klass)
214214
@_supplying_relationship_fields.fetch resource_klass do
215215
relationships = Set.new(resource_klass._relationships.keys.map(&:to_sym))
216216
cur = resource_klass
217-
while cur != JSONAPI::Resource
217+
while !cur.root? # do not traverse beyond the first root resource
218218
if @fields.has_key?(cur._type)
219219
relationships &= @fields[cur._type]
220220
break

test/fixtures/active_record.rb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,12 +1503,10 @@ class EmployeeResource < JSONAPI::Resource
15031503
has_many :expense_entries
15041504
end
15051505

1506-
module BreedResourceFinder
1507-
def self.included(base)
1508-
base.extend ClassMethods
1509-
end
1506+
class PoroResource < JSONAPI::BasicResource
1507+
root_resource
15101508

1511-
module ClassMethods
1509+
class << self
15121510
def find(filters, options = {})
15131511
records = find_breeds(filters, options)
15141512
resources_for(records, options[:context])
@@ -1563,9 +1561,7 @@ def find_breeds_by_keys(keys, options = {})
15631561
end
15641562
end
15651563

1566-
class BreedResource < JSONAPI::Resource
1567-
1568-
resource_finder BreedResourceFinder
1564+
class BreedResource < PoroResource
15691565

15701566
attribute :name, format: :title
15711567

0 commit comments

Comments
 (0)