Skip to content

Commit 3c0fb13

Browse files
committed
Merge branch 'master' into pr/1041
# Conflicts: # lib/jsonapi/active_record_accessor.rb
2 parents 51570ad + 22110a6 commit 3c0fb13

22 files changed

+309
-86
lines changed

.travis.yml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
language: ruby
22
sudo: false
33
env:
4-
- "RAILS_VERSION=4.2.7"
5-
- "RAILS_VERSION=5.0.0"
4+
- "RAILS_VERSION=4.2.8"
5+
- "RAILS_VERSION=5.0.2"
6+
- "RAILS_VERSION=5.1.0"
67
- "RAILS_VERSION=master"
78
rvm:
89
- 2.1.10
9-
- 2.2.6
10-
- 2.3.3
10+
- 2.2.7
11+
- 2.3.4
1112
- 2.4.1
1213
matrix:
1314
exclude:
1415
- rvm: 2.1.10
15-
env: "RAILS_VERSION=5.0.0"
16-
- rvm: 2.4.1
17-
env: "RAILS_VERSION=4.2.7"
16+
env: "RAILS_VERSION=5.0.2"
17+
- rvm: 2.1.10
18+
env: "RAILS_VERSION=5.1.0"
19+
- rvm: 2.1.10
20+
env: "RAILS_VERSION=master"
1821
allow_failures:
1922
- env: "RAILS_VERSION=master"

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2014 Larry Gebhardt
1+
Copyright (c) 2014-2017 Cerebris Corporation
22

33
MIT License
44

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,4 @@ and **paste the content into the issue description**:
6464

6565
## License
6666

67-
Copyright 2014-2016 Cerebris Corporation. MIT License (see LICENSE for details).
67+
Copyright 2014-2017 Cerebris Corporation. MIT License (see LICENSE for details).

Rakefile

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,28 @@ Rake::TestTask.new do |t|
88
t.test_files = FileList['test/**/*_test.rb']
99
end
1010

11-
task default: :test
11+
task default: [:test]
1212

1313
desc 'Run benchmarks'
1414
namespace :test do
1515
Rake::TestTask.new(:benchmark) do |t|
1616
t.pattern = 'test/benchmark/*_benchmark.rb'
1717
end
1818
end
19+
20+
desc 'Test bug report template'
21+
namespace :test do
22+
namespace :bug_report_template do
23+
task :rails_5 do
24+
puts 'Test bug report templates'
25+
jsonapi_resources_root = File.expand_path('..', __FILE__)
26+
chdir_path = File.join(jsonapi_resources_root, 'lib', 'bug_report_templates')
27+
report_env = {'SILENT' => 'true', 'JSONAPI_RESOURCES_PATH' => jsonapi_resources_root}
28+
Bundler.with_clean_env do
29+
Dir.chdir(chdir_path) do
30+
abort('bug report template rails_5_master fails') unless system(report_env, Gem.ruby, 'rails_5_master.rb')
31+
end
32+
end
33+
end
34+
end
35+
end

lib/bug_report_templates/rails_5_master.rb

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
begin
22
require 'bundler/inline'
3+
require 'bundler'
34
rescue LoadError => e
45
STDERR.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
56
raise e
67
end
78

8-
gemfile(true) do
9+
gemfile(true, ui: ENV['SILENT'] ? Bundler::UI::Silent.new : Bundler::UI::Shell.new) do
910
source 'https://rubygems.org'
1011

1112
gem 'rails', require: false
@@ -27,8 +28,17 @@
2728
# prepare active_record database
2829
require 'active_record'
2930

31+
class NullLogger < Logger
32+
def initialize(*_args)
33+
end
34+
35+
def add(*_args, &_block)
36+
end
37+
end
38+
3039
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
31-
ActiveRecord::Base.logger = Logger.new(STDOUT)
40+
ActiveRecord::Base.logger = ENV['SILENT'] ? NullLogger.new : Logger.new(STDOUT)
41+
ActiveRecord::Migration.verbose = !ENV['SILENT']
3242

3343
ActiveRecord::Schema.define do
3444
# Add your schema here
@@ -61,7 +71,7 @@ class YourModelResource < JSONAPI::Resource
6171

6272
class TestApp < Rails::Application
6373
config.root = File.dirname(__FILE__)
64-
config.logger = Logger.new(STDOUT)
74+
config.logger = ENV['SILENT'] ? NullLogger.new : Logger.new(STDOUT)
6575
Rails.logger = config.logger
6676

6777
secrets.secret_token = 'secret_token'

lib/jsonapi/active_record_accessor.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ def default_sort(records, order_options)
231231
order_by_query = "#{associations.last.name}_sorting.#{column_name} #{direction}"
232232
records = records.joins(joins_query).order(order_by_query)
233233
else
234+
field = _resource_klass._attribute_delegated_name(field)
234235
records = records.order(field => direction)
235236
end
236237
end
@@ -279,6 +280,7 @@ def apply_filter(records, filter, value, options = {})
279280
records.where("#{_resource_klass._relationships[filter].table_name}.#{_resource_klass._relationships[filter].primary_key}" => value)
280281
end
281282
else
283+
filter = _resource_klass._attribute_delegated_name(filter)
282284
records.where(filter => value)
283285
end
284286
end

lib/jsonapi/include_directives.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def get_related(current_path)
5252
current_relationship = current_resource_klass._relationships[fragment]
5353
current_resource_klass = current_relationship.try(:resource_klass)
5454
else
55-
warn "[RELATIONSHIP NOT FOUND] Relationship could not be found for #{current_path}."
55+
raise JSONAPI::Exceptions::InvalidInclude.new(current_resource_klass, current_path)
5656
end
5757

5858
include_in_join = @force_eager_load || !current_relationship || current_relationship.eager_load_on_include

lib/jsonapi/relationship.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ def readonly?
6464
@options[:readonly]
6565
end
6666

67+
def redefined_pkey?
68+
belongs_to? && primary_key != resource_klass._default_primary_key
69+
end
70+
6771
class ToOne < Relationship
6872
attr_reader :foreign_key_on
6973

lib/jsonapi/request_parser.rb

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ def parse_fields(resource_klass, fields)
281281
fail JSONAPI::Exceptions::InvalidFieldFormat.new(error_object_overrides)
282282
end
283283

284-
errors = []
285284
# Validate the fields
286285
validated_fields = {}
287286
extracted_fields.each do |type, values|
@@ -293,31 +292,27 @@ def parse_fields(resource_klass, fields)
293292
end
294293
type_resource = Resource.resource_klass_for(resource_klass.module_path + underscored_type.to_s)
295294
rescue NameError
296-
errors.concat(JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides).errors)
297-
rescue JSONAPI::Exceptions::InvalidResource => e
298-
errors.concat(e.errors)
295+
fail JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides)
299296
end
300297

301298
if type_resource.nil?
302-
errors.concat(JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides).errors)
299+
fail JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides)
303300
else
304301
unless values.nil?
305302
valid_fields = type_resource.fields.collect { |key| format_key(key) }
306303
values.each do |field|
307304
if valid_fields.include?(field)
308305
validated_fields[type].push unformat_key(field)
309306
else
310-
errors.concat(JSONAPI::Exceptions::InvalidField.new(type, field, error_object_overrides).errors)
307+
fail JSONAPI::Exceptions::InvalidField.new(type, field, error_object_overrides)
311308
end
312309
end
313310
else
314-
errors.concat(JSONAPI::Exceptions::InvalidField.new(type, 'nil', error_object_overrides).errors)
311+
fail JSONAPI::Exceptions::InvalidField.new(type, 'nil', error_object_overrides)
315312
end
316313
end
317314
end
318315

319-
fail JSONAPI::Exceptions::Errors.new(errors) unless errors.empty?
320-
321316
validated_fields.deep_transform_keys { |key| unformat_key(key) }
322317
end
323318

@@ -331,8 +326,7 @@ def check_include(resource_klass, include_parts)
331326
include_parts.last.partition('.'))
332327
end
333328
else
334-
@errors.concat(JSONAPI::Exceptions::InvalidInclude.new(format_key(resource_klass._type),
335-
include_parts.first).errors)
329+
fail JSONAPI::Exceptions::InvalidInclude.new(format_key(resource_klass._type), include_parts.first)
336330
end
337331
end
338332

@@ -352,12 +346,17 @@ def parse_include_directives(resource_klass, raw_include)
352346

353347
return if included_resources.nil?
354348

355-
result = included_resources.compact.map do |included_resource|
356-
check_include(resource_klass, included_resource.partition('.'))
357-
unformat_key(included_resource).to_s
358-
end
349+
begin
350+
result = included_resources.compact.map do |included_resource|
351+
check_include(resource_klass, included_resource.partition('.'))
352+
unformat_key(included_resource).to_s
353+
end
359354

360-
JSONAPI::IncludeDirectives.new(resource_klass, result)
355+
return JSONAPI::IncludeDirectives.new(resource_klass, result)
356+
rescue JSONAPI::Exceptions::InvalidInclude => e
357+
@errors.concat(e.errors)
358+
return {}
359+
end
361360
end
362361

363362
def parse_filters(resource_klass, filters)
@@ -385,7 +384,7 @@ def parse_filters(resource_klass, filters)
385384
if resource_klass._allowed_filter?(filter)
386385
parsed_filters[filter] = value
387386
else
388-
@errors.concat(JSONAPI::Exceptions::FilterNotAllowed.new(filter).errors)
387+
fail JSONAPI::Exceptions::FilterNotAllowed.new(filter)
389388
end
390389
end
391390

@@ -428,8 +427,7 @@ def check_sort_criteria(resource_klass, sort_criteria)
428427
sort_field = sort_criteria[:field]
429428

430429
unless resource_klass.sortable_field?(sort_field.to_sym, context)
431-
@errors.concat(JSONAPI::Exceptions::InvalidSortCriteria
432-
.new(format_key(resource_klass._type), sort_field).errors)
430+
fail JSONAPI::Exceptions::InvalidSortCriteria.new(format_key(resource_klass._type), sort_field)
433431
end
434432
end
435433

@@ -578,16 +576,14 @@ def unformat_value(resource_klass, attribute, value)
578576
def verify_permitted_params(params, allowed_fields)
579577
formatted_allowed_fields = allowed_fields.collect { |field| format_key(field).to_sym }
580578
params_not_allowed = []
581-
param_errors = []
582579

583580
params.each do |key, value|
584581
case key.to_s
585582
when 'relationships'
586583
value.keys.each do |links_key|
587584
unless formatted_allowed_fields.include?(links_key.to_sym)
588585
if JSONAPI.configuration.raise_if_parameters_not_allowed
589-
param_errors.concat JSONAPI::Exceptions::ParameterNotAllowed.new(
590-
links_key, error_object_overrides).errors
586+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(links_key, error_object_overrides)
591587
else
592588
params_not_allowed.push(links_key)
593589
value.delete links_key
@@ -598,8 +594,7 @@ def verify_permitted_params(params, allowed_fields)
598594
value.each do |attr_key, _attr_value|
599595
unless formatted_allowed_fields.include?(attr_key.to_sym)
600596
if JSONAPI.configuration.raise_if_parameters_not_allowed
601-
param_errors.concat JSONAPI::Exceptions::ParameterNotAllowed.new(
602-
attr_key, error_object_overrides).errors
597+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(attr_key, error_object_overrides)
603598
else
604599
params_not_allowed.push(attr_key)
605600
value.delete attr_key
@@ -610,27 +605,23 @@ def verify_permitted_params(params, allowed_fields)
610605
when 'id'
611606
unless formatted_allowed_fields.include?(:id)
612607
if JSONAPI.configuration.raise_if_parameters_not_allowed
613-
param_errors.concat JSONAPI::Exceptions::ParameterNotAllowed.new(
614-
:id, error_object_overrides).errors
608+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(:id, error_object_overrides)
615609
else
616610
params_not_allowed.push(:id)
617611
params.delete :id
618612
end
619613
end
620614
else
621615
if JSONAPI.configuration.raise_if_parameters_not_allowed
622-
param_errors += JSONAPI::Exceptions::ParameterNotAllowed.new(
623-
key, error_object_overrides).errors
616+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(key, error_object_overrides)
624617
else
625618
params_not_allowed.push(key)
626619
params.delete key
627620
end
628621
end
629622
end
630623

631-
if param_errors.length > 0
632-
fail JSONAPI::Exceptions::Errors.new(param_errors)
633-
elsif params_not_allowed.length > 0
624+
if params_not_allowed.length > 0
634625
params_not_allowed_warnings = params_not_allowed.map do |param|
635626
JSONAPI::Warning.new(code: JSONAPI::PARAM_NOT_ALLOWED,
636627
title: 'Param not allowed',

lib/jsonapi/resource.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,10 @@ def _attribute_options(attr)
757757
default_attribute_options.merge(@_attributes[attr])
758758
end
759759

760+
def _attribute_delegated_name(attr)
761+
@_attributes.fetch(attr.to_sym, {}).fetch(:delegate, attr)
762+
end
763+
760764
def _updatable_attributes
761765
_attributes.map { |key, options| key unless options[:readonly] }.compact
762766
end
@@ -783,7 +787,11 @@ def _model_name
783787
end
784788

785789
def _primary_key
786-
@_primary_key ||= _model_class.respond_to?(:primary_key) ? _model_class.primary_key : :id
790+
@_primary_key ||= _default_primary_key
791+
end
792+
793+
def _default_primary_key
794+
@_default_primary_key ||=_model_class.respond_to?(:primary_key) ? _model_class.primary_key : :id
787795
end
788796

789797
def _cache_field

0 commit comments

Comments
 (0)