Skip to content

Commit 318bf85

Browse files
authored
Merge branch 'release-0-9' into fix--link-builder-on-root-engine
2 parents a37ed5d + b8c57d5 commit 318bf85

File tree

9 files changed

+60
-36
lines changed

9 files changed

+60
-36
lines changed

.travis.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ env:
55
- "RAILS_VERSION=5.0.7.2"
66
- "RAILS_VERSION=5.1.7"
77
- "RAILS_VERSION=5.2.3"
8-
# - "RAILS_VERSION=6.0.0.beta1"
9-
# - "RAILS_VERSION=master"
8+
- "RAILS_VERSION=6.0.0"
109
rvm:
1110
- 2.3.8
1211
- 2.4.7
@@ -19,5 +18,9 @@ matrix:
1918
exclude:
2019
- rvm: 2.6.4
2120
env: "RAILS_VERSION=4.2.11"
21+
- rvm: 2.3.8
22+
env: "RAILS_VERSION=6.0.0"
23+
- rvm: 2.4.7
24+
env: "RAILS_VERSION=6.0.0"
2225
before_install:
23-
- gem install bundler --version 1.17.3
26+
- gem install bundler --version 1.17.3

Gemfile

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,26 @@ source 'https://rubygems.org'
22

33
gemspec
44

5-
platforms :ruby do
6-
gem 'sqlite3', '1.3.10'
7-
end
8-
95
platforms :jruby do
106
gem 'activerecord-jdbcsqlite3-adapter'
117
end
128

139
version = ENV['RAILS_VERSION'] || 'default'
1410

11+
platforms :ruby do
12+
if version.start_with?('4.2', '5.0')
13+
gem 'sqlite3', '~> 1.3.13'
14+
else
15+
gem 'sqlite3', '~> 1.4'
16+
end
17+
end
18+
1519
case version
1620
when 'master'
1721
gem 'railties', { git: 'https://github.com/rails/rails.git' }
1822
gem 'arel', { git: 'https://github.com/rails/arel.git' }
1923
when 'default'
20-
gem 'railties', '>= 5.0'
24+
gem 'railties', '>= 6.0'
2125
else
2226
gem 'railties', "~> #{version}"
2327
end

jsonapi-resources.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ 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 'memory_profiler'
3031
spec.add_dependency 'activerecord', '>= 4.1'
3132
spec.add_dependency 'railties', '>= 4.1'
3233
spec.add_dependency 'concurrent-ruby'

lib/jsonapi/link_builder.rb

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,19 @@ def format_route(route)
105105
end
106106

107107
def formatted_module_path_from_class(klass)
108-
scopes = if @engine
109-
module_scopes_from_class(klass)[1..-1]
110-
else
111-
module_scopes_from_class(klass)
112-
end
113-
114-
unless scopes.empty?
115-
"/#{ scopes.map {|scope| format_route(scope.to_s.underscore)}.compact.join('/') }/"
116-
else
117-
"/"
108+
@_module_path_cache ||= {}
109+
@_module_path_cache[klass] ||= begin
110+
scopes = if @engine
111+
module_scopes_from_class(klass)[1..-1]
112+
else
113+
module_scopes_from_class(klass)
114+
end
115+
116+
unless scopes.empty?
117+
"/#{ scopes.map {|scope| format_route(scope.to_s.underscore)}.compact.join('/') }/"
118+
else
119+
"/"
120+
end
118121
end
119122
end
120123

lib/jsonapi/resource.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ module JSONAPI
55
class Resource
66
include Callbacks
77

8+
DEFAULT_ATTRIBUTE_OPTIONS = { format: :default }.freeze
9+
MODULE_PATH_REGEXP = /::[^:]+\Z/.freeze
10+
811
attr_reader :context
912

1013
define_jsonapi_resources_callbacks :create,
@@ -555,7 +558,7 @@ def attribute(attribute_name, options = {})
555558
end
556559

557560
def default_attribute_options
558-
{ format: :default }
561+
DEFAULT_ATTRIBUTE_OPTIONS
559562
end
560563

561564
def relationship(*attrs)
@@ -1133,7 +1136,7 @@ def module_path
11331136
if name == 'JSONAPI::Resource'
11341137
''
11351138
else
1136-
name =~ /::[^:]+\Z/ ? ($`.freeze.gsub('::', '/') + '/').underscore : ''
1139+
name =~ MODULE_PATH_REGEXP ? ($`.freeze.gsub('::', '/') + '/').underscore : ''
11371140
end
11381141
end
11391142

@@ -1351,7 +1354,8 @@ def preload_included_fragments(resources, records, serializer, options)
13511354
rel_id = row[index+1]
13521355
assoc_rels = res.preloaded_fragments[rel_name]
13531356
if index == path.length - 1
1354-
assoc_rels[rel_id] = target_resources[klass.name].fetch(rel_id)
1357+
association_res = target_resources[klass.name].fetch(rel_id, nil)
1358+
assoc_rels[rel_id] = association_res if association_res
13551359
else
13561360
res = assoc_rels[rel_id]
13571361
end

lib/jsonapi/resource_serializer.rb

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,6 @@ def relationships_hash(source, fetchable_fields, include_directives = {})
287287
include_linkage = ia && ia[:include]
288288
include_linked_children = ia && !ia[:include_related].empty?
289289

290-
options = { filters: ia && ia[:include_filters] || {} }
291290
if field_set.include?(name)
292291
ro = relationship_object(source, relationship, include_linkage)
293292
hash[format_key(name)] = ro unless ro.blank?
@@ -300,6 +299,7 @@ def relationships_hash(source, fetchable_fields, include_directives = {})
300299
resources = if source.preloaded_fragments.has_key?(format_key(name))
301300
source.preloaded_fragments[format_key(name)].values
302301
else
302+
options = { filters: ia && ia[:include_filters] || {} }
303303
[source.public_send(name, options)].flatten(1).compact
304304
end
305305
resources.each do |resource|
@@ -468,16 +468,20 @@ def relationship_object(source, relationship, include_linkage = false)
468468

469469
# Extracts the foreign key value for a to_one relationship.
470470
def foreign_key_value(source, relationship)
471-
related_resource_id = if source.preloaded_fragments.has_key?(format_key(relationship.name))
472-
source.preloaded_fragments[format_key(relationship.name)].values.first.try(:id)
473-
elsif source.respond_to?("#{relationship.name}_id")
474-
# If you have direct access to the underlying id, you don't have to load the relationship
475-
# which can save quite a lot of time when loading a lot of data.
476-
# This does not apply to e.g. has_one :through relationships.
477-
source.public_send("#{relationship.name}_id")
478-
else
479-
source.public_send(relationship.name).try(:id)
480-
end
471+
# If you have changed the key_name, don't even try to look at `"#{relationship.name}_id"`
472+
# just load the association and call the custom key_name
473+
foreign_key_type_changed = relationship.options[:foreign_key_type_changed] || false
474+
related_resource_id =
475+
if source.preloaded_fragments.has_key?(format_key(relationship.name))
476+
source.preloaded_fragments[format_key(relationship.name)].values.first.try(:id)
477+
elsif !foreign_key_type_changed && source.respond_to?("#{relationship.name}_id")
478+
# If you have direct access to the underlying id, you don't have to load the relationship
479+
# which can save quite a lot of time when loading a lot of data.
480+
# This does not apply to e.g. has_one :through relationships.
481+
source.public_send("#{relationship.name}_id")
482+
else
483+
source.public_send(relationship.name).try(:id)
484+
end
481485
return nil unless related_resource_id
482486
@id_formatter.format(related_resource_id)
483487
end

lib/jsonapi/resources/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module JSONAPI
22
module Resources
3-
VERSION = '0.9.10'
3+
VERSION = '0.9.11'
44
end
55
end

test/benchmark/request_benchmark.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ def setup
77
end
88

99
def bench_large_index_request_uncached
10-
10.times do
10+
100.times do
1111
assert_jsonapi_get '/api/v2/books?include=bookComments,bookComments.author'
1212
end
1313
end
1414

1515
def bench_large_index_request_caching
1616
cache = ActiveSupport::Cache::MemoryStore.new
1717
with_resource_caching(cache) do
18-
10.times do
18+
100.times do
1919
assert_jsonapi_get '/api/v2/books?include=bookComments,bookComments.author'
2020
end
2121
end

test/test_helper.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
require 'minitest/mock'
2525
require 'jsonapi-resources'
2626
require 'pry'
27+
require 'memory_profiler'
2728

2829
require File.expand_path('../helpers/value_matchers', __FILE__)
2930
require File.expand_path('../helpers/assertions', __FILE__)
@@ -470,7 +471,8 @@ class ActionDispatch::IntegrationTest
470471
fixtures :all
471472

472473
def assert_jsonapi_response(expected_status, msg = nil)
473-
assert_equal JSONAPI::MEDIA_TYPE, response.content_type
474+
media_type = Rails::VERSION::MAJOR >= 6 ? response.media_type : response.content_type
475+
assert_equal JSONAPI::MEDIA_TYPE, media_type
474476
if status != expected_status && status >= 400
475477
pp json_response rescue nil
476478
end
@@ -638,6 +640,9 @@ def self.run_one_method(klass, method_name, reporter)
638640
end
639641
end
640642
puts
643+
if ENV["MEMORY_PROFILER"]
644+
MemoryProfiler.report(allow_files: 'lib/jsonapi') { super(klass, method_name, reporter) }.pretty_print
645+
end
641646
end
642647
end
643648

0 commit comments

Comments
 (0)