Skip to content

Commit 01ba9a0

Browse files
committed
V0.11 refactor resource classes to modules (#1406)
* Restore previous include directives behavior * Default sort use _primary_key * Remove support for pluck attributes * Pass relationship instead of relationship name * Update copyright date * Ignore docker-compose override files * add _relation_name method * Rework resource class to support using modules for retrieving resources by way of a `resource_retrieval_strategy` Removes BasicResource class and replaces ActiveRelationResource with a module * Use `_relationship` helper method * Add ActiveRelationRetrieval Allows retrieval of resources by querying the primary table and joining the source table - the opposite of the v10 version * Skip extra pluck queries when not caching a resource * Test Cleanup * Adjust tested query counts based on default_resource_retrieval_strategy * create_implicit_polymorphic_type_relationships * Add ActiveRelationRetrievalV09 * Move resource down in the load order * Use underscore instead of downcase * Refactor Resource to load retrieval strategy as class loads * Simplify loading resource retrieval strategy modules Add SimpleResource that does not load a resource retrieval strategy module * Remove no longer need deferred_relationship code * Add warning about potentially unused `records_for_populate` * Rework loading the resource_retrieval_strategy to fix issue in real projects * Use SortedSets for resource_identities * Add sorted_set gem * Remove rails 5 support
1 parent f2bcba9 commit 01ba9a0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+5686
-3057
lines changed

.github/workflows/ruby.yml

-14
Original file line numberDiff line numberDiff line change
@@ -47,35 +47,21 @@ jobs:
4747
- '7.0'
4848
- '6.1'
4949
- '6.0'
50-
- '5.2'
51-
- '5.1'
5250
database_url:
5351
- sqlite3:test_db
5452
- postgresql://postgres:password@localhost:5432/test
5553
- mysql2://root:[email protected]:3306/test
5654
exclude:
5755
- ruby: '3.2'
5856
rails: '6.0'
59-
- ruby: '3.2'
60-
rails: '5.2'
61-
- ruby: '3.2'
62-
rails: '5.1'
6357
- ruby: '3.1'
6458
rails: '6.0'
65-
- ruby: '3.1'
66-
rails: '5.2'
6759
- ruby: '3.1'
6860
rails: '5.1'
6961
- ruby: '3.0'
7062
rails: '6.0'
71-
- ruby: '3.0'
72-
rails: '5.2'
73-
- ruby: '3.0'
74-
rails: '5.1'
7563
- ruby: '2.6'
7664
rails: '7.0'
77-
- database_url: postgresql://postgres:password@localhost:5432/test
78-
rails: '5.1'
7965
env:
8066
RAILS_VERSION: ${{ matrix.rails }}
8167
DATABASE_URL: ${{ matrix.database_url }}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ test_db
2323
test_db-journal
2424
.idea
2525
*.iml
26+
*.override.yml

LICENSE.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2014-2021 Cerebris Corporation
1+
Copyright (c) 2014-2023 Cerebris Corporation
22

33
MIT License
44

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,4 @@ and **paste the content into the issue description or attach as a file**:
110110

111111
## License
112112

113-
Copyright 2014-2021 Cerebris Corporation. MIT License (see LICENSE for details).
113+
Copyright 2014-2023 Cerebris Corporation. MIT License (see LICENSE for details).

jsonapi-resources.gemspec

+2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ Gem::Specification.new do |spec|
2727
spec.add_development_dependency 'pry'
2828
spec.add_development_dependency 'concurrent-ruby-ext'
2929
spec.add_development_dependency 'database_cleaner'
30+
spec.add_development_dependency 'hashie'
3031
spec.add_dependency 'activerecord', '>= 5.1'
3132
spec.add_dependency 'railties', '>= 5.1'
3233
spec.add_dependency 'concurrent-ruby'
34+
spec.add_dependency 'sorted_set'
3335
end

lib/jsonapi-resources.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
require 'jsonapi/resources/railtie'
44
require 'jsonapi/naive_cache'
55
require 'jsonapi/compiled_json'
6-
require 'jsonapi/basic_resource'
7-
require 'jsonapi/active_relation_resource'
6+
require 'jsonapi/active_relation_retrieval'
7+
require 'jsonapi/active_relation_retrieval_v09'
8+
require 'jsonapi/active_relation_retrieval_v10'
9+
require 'jsonapi/resource_common'
810
require 'jsonapi/resource'
11+
require 'jsonapi/simple_resource'
912
require 'jsonapi/cached_response_fragment'
1013
require 'jsonapi/response_document'
1114
require 'jsonapi/acts_as_resource_controller'
@@ -37,6 +40,7 @@
3740
require 'jsonapi/link_builder'
3841
require 'jsonapi/active_relation/adapters/join_left_active_record_adapter'
3942
require 'jsonapi/active_relation/join_manager'
43+
require 'jsonapi/active_relation/join_manager_v10'
4044
require 'jsonapi/resource_identity'
4145
require 'jsonapi/resource_fragment'
4246
require 'jsonapi/resource_tree'

lib/jsonapi/active_relation/join_manager.rb

+27-11
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,22 @@ class JoinManager
77
attr_reader :resource_klass,
88
:source_relationship,
99
:resource_join_tree,
10-
:join_details
10+
:join_details,
11+
:through_source
1112

1213
def initialize(resource_klass:,
1314
source_relationship: nil,
15+
source_resource_klass: nil,
16+
through_source: false,
1417
relationships: nil,
1518
filters: nil,
1619
sort_criteria: nil)
1720

1821
@resource_klass = resource_klass
22+
@source_resource_klass = source_resource_klass
1923
@join_details = nil
2024
@collected_aliases = Set.new
25+
@through_source = through_source
2126

2227
@resource_join_tree = {
2328
root: {
@@ -45,7 +50,7 @@ def join(records, options)
4550
# this method gets the join details whether they are on a relationship or are just pseudo details for the base
4651
# resource. Specify the resource type for polymorphic relationships
4752
#
48-
def source_join_details(type=nil)
53+
def source_join_details(type = nil)
4954
if source_relationship
5055
related_resource_klass = type ? resource_klass.resource_klass_for(type) : source_relationship.resource_klass
5156
segment = PathSegment::Relationship.new(relationship: source_relationship, resource_klass: related_resource_klass)
@@ -90,14 +95,20 @@ def self.get_join_arel_node(records, options = {})
9095
end
9196

9297
def self.alias_from_arel_node(node)
93-
case node.left
98+
# case node.left
99+
case node&.left
94100
when Arel::Table
95101
node.left.name
96102
when Arel::Nodes::TableAlias
97103
node.left.right
98104
when Arel::Nodes::StringJoin
99105
# :nocov:
100-
warn "alias_from_arel_node: Unsupported join type - use custom filtering and sorting"
106+
warn "alias_from_arel_node: Unsupported join type `Arel::Nodes::StringJoin` - use custom filtering and sorting"
107+
nil
108+
# :nocov:
109+
else
110+
# :nocov:
111+
warn "alias_from_arel_node: Unsupported join type `#{node&.left.to_s}`"
101112
nil
102113
# :nocov:
103114
end
@@ -163,7 +174,8 @@ def perform_joins(records, options)
163174
options: options)
164175
}
165176

166-
details = {alias: self.class.alias_from_arel_node(join_node), join_type: join_type}
177+
join_alias = self.class.alias_from_arel_node(join_node)
178+
details = {alias: join_alias, join_type: join_type}
167179

168180
if relationship == source_relationship
169181
if relationship.polymorphic? && relationship.belongs_to?
@@ -175,15 +187,19 @@ def perform_joins(records, options)
175187

176188
# We're adding the source alias with two keys. We only want the check for duplicate aliases once.
177189
# See the note in `add_join_details`.
178-
check_for_duplicate_alias = !(relationship == source_relationship)
179-
add_join_details(PathSegment::Relationship.new(relationship: relationship, resource_klass: related_resource_klass), details, check_for_duplicate_alias)
190+
check_for_duplicate_alias = relationship != source_relationship
191+
path_segment = PathSegment::Relationship.new(relationship: relationship,
192+
resource_klass: related_resource_klass)
193+
194+
add_join_details(path_segment, details, check_for_duplicate_alias)
180195
end
181196
end
182197
records
183198
end
184199

185200
def add_join(path, default_type = :inner, default_polymorphic_join_type = :left)
186-
if source_relationship
201+
# puts "add_join #{path} default_type=#{default_type} default_polymorphic_join_type=#{default_polymorphic_join_type}"
202+
if source_relationship && through_source
187203
if source_relationship.polymorphic?
188204
# Polymorphic paths will come it with the resource_type as the first segment (for example `#documents.comments`)
189205
# We just need to prepend the relationship portion the
@@ -195,9 +211,9 @@ def add_join(path, default_type = :inner, default_polymorphic_join_type = :left)
195211
sourced_path = path
196212
end
197213

198-
join_manager, _field = parse_path_to_tree(sourced_path, resource_klass, default_type, default_polymorphic_join_type)
214+
join_tree, _field = parse_path_to_tree(sourced_path, resource_klass, default_type, default_polymorphic_join_type)
199215

200-
@resource_join_tree[:root].deep_merge!(join_manager) { |key, val, other_val|
216+
@resource_join_tree[:root].deep_merge!(join_tree) { |key, val, other_val|
201217
if key == :join_type
202218
if val == other_val
203219
val
@@ -294,4 +310,4 @@ def add_relationships(relationships)
294310
end
295311
end
296312
end
297-
end
313+
end

0 commit comments

Comments
 (0)