From 36f432dea1f26805ed86c8e614874e1764def7a9 Mon Sep 17 00:00:00 2001 From: Emil Kampp <40206+ekampp@users.noreply.github.com> Date: Thu, 9 Jul 2020 08:17:16 +0200 Subject: [PATCH 01/17] Change to maintained fork of fasts_jsonapi --- jsonapi.rb.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonapi.rb.gemspec b/jsonapi.rb.gemspec index dcc0295..0a2884e 100644 --- a/jsonapi.rb.gemspec +++ b/jsonapi.rb.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |spec| end spec.require_paths = ['lib'] - spec.add_dependency 'fast_jsonapi', '~> 1.5' + spec.add_dependency 'jsonapi-serializer', '~> 2.0' spec.add_dependency 'ransack' spec.add_dependency 'rack' From 5e864a2950c97b77fbfaa9bdcd068187ee9f0de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Thu, 9 Jul 2020 13:59:10 +0100 Subject: [PATCH 02/17] Switch to `jsonapi/serializer`. --- Gemfile | 2 -- README.md | 6 +++--- lib/jsonapi/error_serializer.rb | 4 ++-- lib/jsonapi/rails.rb | 31 ++++++++++++++++++++++++------- spec/dummy.rb | 4 ++-- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Gemfile b/Gemfile index ce256d1..b77b5cb 100644 --- a/Gemfile +++ b/Gemfile @@ -2,5 +2,3 @@ source 'https://rubygems.org' # Specify your gem's dependencies in jsonapi.gemspec gemspec - -gem 'jsonapi-rspec', git: 'https://github.com/jsonapi-rb/jsonapi-rspec.git' diff --git a/README.md b/README.md index 85e7983..453d293 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Main goals: The available features include: - * object serialization (powered by Fast JSON API) + * object serialization (powered by JSON:API Serializer, was `fast_jsonapi`) * [error handling](https://jsonapi.org/format/#errors) (parameters, validation, generic errors) * fetching of the data (support for @@ -44,7 +44,7 @@ The available features include: ## But how? -Mainly by leveraging [Fast JSON API](https://github.com/Netflix/fast_jsonapi) +Mainly by leveraging [JSON:API Serializer](https://github.com/jsonapi-serializer/jsonapi-serializer) and [Ransack](https://github.com/activerecord-hackery/ransack). Thanks to everyone who worked on these amazing projects! @@ -100,7 +100,7 @@ The naming scheme follows the `ModuleName::ClassNameSerializer` for an instance of the `ModuleName::ClassName`. Please follow the -[Fast JSON API guide](https://github.com/Netflix/fast_jsonapi#serializer-definition) +[JSON:API Serializer guide](https://github.com/jsonapi-serializer/jsonapi-serializer#serializer-definition) on how to define a serializer. To provide a different naming scheme implement the `jsonapi_serializer_class` diff --git a/lib/jsonapi/error_serializer.rb b/lib/jsonapi/error_serializer.rb index 6b5fb6c..8252156 100644 --- a/lib/jsonapi/error_serializer.rb +++ b/lib/jsonapi/error_serializer.rb @@ -1,9 +1,9 @@ -require 'fast_jsonapi' +require 'jsonapi/serializer' module JSONAPI # A simple error serializer class ErrorSerializer - include FastJsonapi::ObjectSerializer + include JSONAPI::Serializer set_id :object_id set_type :error diff --git a/lib/jsonapi/rails.rb b/lib/jsonapi/rails.rb index 9aae0dc..5f8aef4 100644 --- a/lib/jsonapi/rails.rb +++ b/lib/jsonapi/rails.rb @@ -42,8 +42,9 @@ def self.add_errors_renderer! many = JSONAPI::Rails.is_collection?(resource, options[:is_collection]) resource = [resource] unless many - return JSONAPI::ErrorSerializer.new(resource, options) - .serialized_json unless resource.is_a?(ActiveModel::Errors) + return JSONAPI::Rails.serializer_to_json( + JSONAPI::ErrorSerializer.new(resource, options) + ) unless resource.is_a?(ActiveModel::Errors) errors = [] model = resource.instance_variable_get('@base') @@ -66,9 +67,11 @@ def self.add_errors_renderer! end end - JSONAPI::ActiveModelErrorSerializer.new( - errors, params: { model: model, model_serializer: model_serializer } - ).serialized_json + JSONAPI::Rails.serializer_to_json( + JSONAPI::ActiveModelErrorSerializer.new( + errors, params: { model: model, model_serializer: model_serializer } + ) + ) end end @@ -100,13 +103,15 @@ def self.add_renderer! serializer_class = JSONAPI::Rails.serializer_class(resource, many) end - serializer_class.new(resource, options).serialized_json + JSONAPI::Rails.serializer_to_json( + serializer_class.new(resource, options) + ) end end # Checks if an object is a collection # - # Stolen from [FastJsonapi::ObjectSerializer], instance method. + # Stolen from [JSONAPI::Serializer], instance method. # # @param resource [Object] to check # @param force_is_collection [NilClass] flag to overwrite @@ -126,5 +131,17 @@ def self.serializer_class(resource, is_collection) "#{klass.name}Serializer".constantize end + + # Lazily returns the serializer JSON + # + # @param serializer [Object] to evaluate + # @return [String] + def self.serializer_to_json(serializer) + if serializer.respond_to?(:serialized_json) + serializer.serialized_json + else + serializer.serializable_hash.to_json + end + end end end diff --git a/spec/dummy.rb b/spec/dummy.rb index 9239455..6f0c434 100644 --- a/spec/dummy.rb +++ b/spec/dummy.rb @@ -40,7 +40,7 @@ class Note < ActiveRecord::Base end class CustomNoteSerializer - include FastJsonapi::ObjectSerializer + include JSONAPI::Serializer set_type :note belongs_to :user @@ -48,7 +48,7 @@ class CustomNoteSerializer end class UserSerializer - include FastJsonapi::ObjectSerializer + include JSONAPI::Serializer has_many :notes, serializer: CustomNoteSerializer attributes(:last_name, :created_at, :updated_at) From 750490aa46f9ccb4c599534d72d696c80112e398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Thu, 9 Jul 2020 14:12:31 +0100 Subject: [PATCH 03/17] Do not run rubocop on Rails 4. --- Rakefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 6572d7d..631bf5e 100644 --- a/Rakefile +++ b/Rakefile @@ -24,7 +24,11 @@ RuboCop::RakeTask.new('qa:code') do |task| end desc('Run CI QA tasks') -task(qa: ['qa:docs', 'qa:code']) +if ENV['RAILS_VERSION'].to_s.include?('4') + task(qa: ['qa:docs']) +else + task(qa: ['qa:docs', 'qa:code']) +end RSpec::Core::RakeTask.new(spec: :qa) task(default: :spec) From 45ccba6f2cf9396e1b5a886dd04d8e2f0af9b8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Thu, 9 Jul 2020 14:16:24 +0100 Subject: [PATCH 04/17] Version bump. --- lib/jsonapi/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jsonapi/version.rb b/lib/jsonapi/version.rb index 9eee5f9..7134ef7 100644 --- a/lib/jsonapi/version.rb +++ b/lib/jsonapi/version.rb @@ -1,3 +1,3 @@ module JSONAPI - VERSION = '1.5.7' + VERSION = '1.6.0' end From 01db1e97956703bdd323483642672888840eb56f Mon Sep 17 00:00:00 2001 From: Finn Lawrence Date: Fri, 27 Nov 2020 00:45:12 +1300 Subject: [PATCH 05/17] Add Count of Records to Pagination (#29) * Add total records to pagination * Spec for total records --- lib/jsonapi/pagination.rb | 4 ++++ spec/pagination_spec.rb | 26 +++++++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/jsonapi/pagination.rb b/lib/jsonapi/pagination.rb index 4d267cf..178dd8c 100644 --- a/lib/jsonapi/pagination.rb +++ b/lib/jsonapi/pagination.rb @@ -82,6 +82,10 @@ def jsonapi_pagination_meta(resources) numbers[:last] = last_page end + if total.present? + numbers[:records] = total + end + numbers end diff --git a/spec/pagination_spec.rb b/spec/pagination_spec.rb index 879c883..ec1c3c4 100644 --- a/spec/pagination_spec.rb +++ b/spec/pagination_spec.rb @@ -17,7 +17,13 @@ it do expect(response_json['data'].size).to eq(0) expect(response_json['meta']) - .to eq('many' => true, 'pagination' => { 'current' => 1 }) + .to eq( + 'many' => true, + 'pagination' => { + 'current' => 1, + 'records' => 0 + } + ) end context 'with users' do @@ -68,7 +74,8 @@ 'first' => 1, 'prev' => 1, 'next' => 3, - 'last' => 3 + 'last' => 3, + 'records' => 3 ) end end @@ -83,7 +90,8 @@ 'first' => 1, 'prev' => 1, 'next' => 3, - 'last' => 3 + 'last' => 3, + 'records' => 3 ) expect(response_json).to have_link(:self) @@ -122,7 +130,8 @@ expect(response_json['meta']['pagination']).to eq( 'current' => 3, 'first' => 1, - 'prev' => 2 + 'prev' => 2, + 'records' => 3 ) expect(response_json).to have_link(:self) @@ -161,7 +170,8 @@ expect(response_json['meta']['pagination']).to eq( 'current' => 5, 'first' => 1, - 'prev' => 4 + 'prev' => 4, + 'records' => 3 ) end end @@ -173,7 +183,8 @@ expect(response_json['meta']['pagination']).to eq( 'current' => 5, 'first' => 1, - 'prev' => 4 + 'prev' => 4, + 'records' => 3 ) expect(response_json).to have_link(:self) @@ -209,7 +220,8 @@ expect(response_json['meta']['pagination']).to eq( 'current' => 1, 'next' => 2, - 'last' => 3 + 'last' => 3, + 'records' => 3 ) expect(response_json).not_to have_link(:prev) From c3255b8bb6908deaa3851f62170e08f347bef22c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Thu, 26 Nov 2020 11:51:26 +0000 Subject: [PATCH 06/17] Updated GH Actions config. --- .github/workflows/ci.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc088e2..53de5fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,23 +4,23 @@ on: [push, pull_request] jobs: ruby_rails_test_matrix: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest strategy: matrix: - ruby: [2.4, 2.6] - rails: [4, 5, 6] + ruby: [2.4, 2.7] + rails: [5, 6] exclude: - ruby: 2.4 rails: 6 steps: - - uses: actions/checkout@master + - uses: actions/checkout@v2 - - name: Sets up the environment - uses: actions/setup-ruby@v1 + - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} + bundler-cache: true - name: Runs code QA and tests env: @@ -29,8 +29,7 @@ jobs: rm -rf Gemfile.lock sudo apt-get update sudo apt-get install libsqlite3-dev - gem uninstall bundler -a --force - gem install bundler -v '~> 1' echo $RAILS_VERSION | grep -q '4' && export SQLITE3_VERSION='~> 1.3.6' + echo $RAILS_VERSION | grep -q '4' && RUBOCOP_VERSION='~> 0.77' bundle - rake + bundle exec rake From efa76c104cc7ad9247964760112c7d0ca0e314e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Thu, 26 Nov 2020 15:23:13 +0000 Subject: [PATCH 07/17] Updated rubocop bits. --- .rubocop.yml | 9 +++++++++ jsonapi.rb.gemspec | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index b287531..6b68123 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,12 +4,21 @@ inherit_gem: require: rubocop-performance +AllCops: + NewCops: enable + Performance: Enabled: true Rails: Enabled: true +Rails/Pluck: + Enabled: false + +Rails/NegateInclude: + Enabled: false + Style/StringLiterals: Enabled: true EnforcedStyle: single_quotes diff --git a/jsonapi.rb.gemspec b/jsonapi.rb.gemspec index 0a2884e..ff37c21 100644 --- a/jsonapi.rb.gemspec +++ b/jsonapi.rb.gemspec @@ -34,7 +34,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'jsonapi-rspec' spec.add_development_dependency 'yardstick' spec.add_development_dependency 'rubocop-rails_config' - spec.add_development_dependency 'rubocop' + spec.add_development_dependency 'rubocop', ENV['RUBOCOP_VERSION'] spec.add_development_dependency 'simplecov' spec.add_development_dependency 'rubocop-performance' end From 5b0c51cc087424e1866a5bf02fdb2ab4f655328a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Thu, 26 Nov 2020 15:24:06 +0000 Subject: [PATCH 08/17] Loosen up jsonapi-serializer deps. Allow builds sans git. --- jsonapi.rb.gemspec | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/jsonapi.rb.gemspec b/jsonapi.rb.gemspec index ff37c21..5f1d3d5 100644 --- a/jsonapi.rb.gemspec +++ b/jsonapi.rb.gemspec @@ -16,12 +16,11 @@ Gem::Specification.new do |spec| spec.homepage = 'https://github.com/stas/jsonapi.rb' spec.license = 'MIT' - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) } - end + spec.files = Dir.glob('{lib,spec}/**/*', File::FNM_DOTMATCH) + spec.files += %w(LICENSE.txt README.md) spec.require_paths = ['lib'] - spec.add_dependency 'jsonapi-serializer', '~> 2.0' + spec.add_dependency 'jsonapi-serializer' spec.add_dependency 'ransack' spec.add_dependency 'rack' From 9dee9d8f99cd028aee67deb5ddb99a535af13c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Thu, 26 Nov 2020 15:24:17 +0000 Subject: [PATCH 09/17] Fixed failed tests. --- lib/jsonapi/active_model_error_serializer.rb | 3 --- lib/jsonapi/error_serializer.rb | 7 ++++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/jsonapi/active_model_error_serializer.rb b/lib/jsonapi/active_model_error_serializer.rb index 8d9fead..59a3e3c 100644 --- a/lib/jsonapi/active_model_error_serializer.rb +++ b/lib/jsonapi/active_model_error_serializer.rb @@ -3,9 +3,6 @@ module JSONAPI # [ActiveModel::Errors] serializer class ActiveModelErrorSerializer < ErrorSerializer - set_id :object_id - set_type :error - attribute :status do '422' end diff --git a/lib/jsonapi/error_serializer.rb b/lib/jsonapi/error_serializer.rb index 8252156..4886a13 100644 --- a/lib/jsonapi/error_serializer.rb +++ b/lib/jsonapi/error_serializer.rb @@ -5,7 +5,6 @@ module JSONAPI class ErrorSerializer include JSONAPI::Serializer - set_id :object_id set_type :error # Object/Hash attribute helpers. @@ -15,6 +14,12 @@ class ErrorSerializer end end + # Overwrite the ID extraction method, to skip validations + # + # @return [NilClass] + def self.id_from_record(_record, _params) + end + # Remap the root key to `errors` # # @return [Hash] From 3a31499b6e36b623540f04c2dedf31e116016a2f Mon Sep 17 00:00:00 2001 From: Maximilian Haack Date: Sun, 29 Nov 2020 13:13:11 +0100 Subject: [PATCH 10/17] Use `#size` instead of `#count` for pagination `#count` will always execute an SQL COUNT query whereas `#size` will check if the records are already loaded (and then call `#length`). It only executes a count when necessary. See https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-size --- lib/jsonapi/pagination.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jsonapi/pagination.rb b/lib/jsonapi/pagination.rb index 178dd8c..3936202 100644 --- a/lib/jsonapi/pagination.rb +++ b/lib/jsonapi/pagination.rb @@ -63,7 +63,7 @@ def jsonapi_pagination_meta(resources) numbers = { current: page } if resources.respond_to?(:unscope) - total = resources.unscope(:limit, :offset, :order).count() + total = resources.unscope(:limit, :offset, :order).size else # Try to fetch the cached size first total = resources.instance_variable_get(:@original_size) From 3a685a766e12fd5be9176af7e2a54c5c2a7f7a62 Mon Sep 17 00:00:00 2001 From: Joe Korzeniewski Date: Sat, 12 Dec 2020 05:32:06 -0500 Subject: [PATCH 11/17] Total count and configurable default per_page (#31) * Remove hard coded maximum per-page limit of 30. * Don't include total in pagination links. * Wrap default per_page in a method. * Update readme with jsonapi_page_size example. * Skip :records in pagination with next. --- README.md | 10 ++++++++++ lib/jsonapi/pagination.rb | 13 ++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 453d293..fe94452 100644 --- a/README.md +++ b/README.md @@ -290,6 +290,7 @@ class MyController < ActionController::Base render jsonapi: paginated end end + end ``` @@ -306,6 +307,15 @@ use the `jsonapi_pagination_meta` method: end ``` + +If you want to change the default number of items per page, use the +`jsonapi_page_size` method: + +```ruby + def jsonapi_page_size + 30 + end +``` ### Deserialization `JSONAPI::Deserialization` provides a helper to transform a `JSONAPI` document diff --git a/lib/jsonapi/pagination.rb b/lib/jsonapi/pagination.rb index 3936202..03ae22d 100644 --- a/lib/jsonapi/pagination.rb +++ b/lib/jsonapi/pagination.rb @@ -43,6 +43,8 @@ def jsonapi_pagination(resources) original_url = request.base_url + request.path + '?' pagination.each do |page_name, number| + next if page_name == :records + original_params[:page][:number] = number links[page_name] = original_url + CGI.unescape( original_params.to_query @@ -93,16 +95,21 @@ def jsonapi_pagination_meta(resources) # # @return [Array] with the offset, limit and the current page number def jsonapi_pagination_params - def_per_page = self.class.const_get(:JSONAPI_PAGE_SIZE).to_i - pagination = params[:page].try(:slice, :number, :size) || {} per_page = pagination[:size].to_f.to_i - per_page = def_per_page if per_page > def_per_page || per_page < 1 + per_page = jsonapi_page_size if per_page < 1 num = [1, pagination[:number].to_f.to_i].max [(num - 1) * per_page, per_page, num] end + # Retrieves the default page size + # + # @return [Integer] + def jsonapi_page_size + self.class.const_get(:JSONAPI_PAGE_SIZE).to_i + end + # Fallback to Rack's parsed query string when Rails is not available # # @return [Hash] From f107416854d3e33c831e3db9945e65fad548dec6 Mon Sep 17 00:00:00 2001 From: Maximilian Haack Date: Sun, 14 Feb 2021 02:23:29 +0100 Subject: [PATCH 12/17] Add Rails 6.0 to test matrix --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53de5fe..bbccaef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: ruby: [2.4, 2.7] - rails: [5, 6] + rails: ['5', '6.0', '6'] exclude: - ruby: 2.4 rails: 6 From 870a7f0265a970ef927c7e5dbeaad7d70804c1a7 Mon Sep 17 00:00:00 2001 From: Maximilian Haack Date: Sun, 14 Feb 2021 02:27:41 +0100 Subject: [PATCH 13/17] Handle Rails 6.1 ActiveModel::Error#detail Starting with Rails 6.1 ActiveModel::Error is an actual class: > Active Model's errors are now objects with an interface that allows > your application to more easily handle and interact with errors thrown > by models. The feature[1] includes a query interface, enables more > precise testing, and access to error details. > > [1] https://github.com/rails/rails/pull/32313 As a result of this `resource.details` looks slightly different than in previous versions and notably doesn't contain `:message` anymore, if `object.errors.add(:something, message: 'some error')` was used to specify a validation error. https://github.com/rails/rails/blob/2a7ff0a5f54979b14b19f827c99295297dda411d/activemodel/lib/active_model/error.rb#L149 From the test suite: ``` note.errors.add(:title, message: 'has typos') if note.errors.key?(:title) ``` Rails 6.0: ``` { :title=>[{:error=>:invalid, :value=>"BAD_TITLE"}, {:error=>{:message=>"has typos"}}], :quantity=>[{:error=>:less_than, :value=>109, :count=>100}] } ``` Rails 6.1: ``` { :title=>[{:error=>:invalid, :value=>"BAD_TITLE"}, {:error=>:invalid}], :quantity=>[{:error=>:less_than, :value=>100, :count=>100}] } ``` The patch addresses this change by merging the error.message into its detail. --- lib/jsonapi/rails.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/jsonapi/rails.rb b/lib/jsonapi/rails.rb index 5f8aef4..8d29d17 100644 --- a/lib/jsonapi/rails.rb +++ b/lib/jsonapi/rails.rb @@ -55,8 +55,18 @@ def self.add_errors_renderer! model_serializer = JSONAPI::Rails.serializer_class(model, false) end - details = resource.messages - details = resource.details if resource.respond_to?(:details) + details = {} + if ::Rails::VERSION::MAJOR >= 6 && ::Rails::VERSION::MINOR >= 1 + resource.map do |error| + attr = error.attribute + details[attr] ||= [] + details[attr] << error.detail.merge(message: error.message) + end + elsif resource.respond_to?(:details) + details = resource.details + else + details = resource.messages + end details.each do |error_key, error_hashes| error_hashes.each do |error_hash| From 4f7d4b76e32bd91ff3e919fb5c8d141df9b51b7f Mon Sep 17 00:00:00 2001 From: Maximilian Haack Date: Sun, 14 Feb 2021 02:43:20 +0100 Subject: [PATCH 14/17] Expect different blank validation detail Rails 6.1 Due to the change in b019536 the validation error message for a required field changes from "$x can't be blank" to "$x must exist". --- spec/errors_spec.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/spec/errors_spec.rb b/spec/errors_spec.rb index a67e0ac..da3d0f5 100644 --- a/spec/errors_spec.rb +++ b/spec/errors_spec.rb @@ -56,8 +56,13 @@ .to eq(Rack::Utils::HTTP_STATUS_CODES[422]) expect(response_json['errors'][0]['source']) .to eq('pointer' => '/data/relationships/user') - expect(response_json['errors'][0]['detail']) - .to eq('User can\'t be blank') + if Rails::VERSION::MAJOR >= 6 && Rails::VERSION::MINOR >= 1 + expect(response_json['errors'][0]['detail']) + .to eq('User must exist') + else + expect(response_json['errors'][0]['detail']) + .to eq('User can\'t be blank') + end end context 'required by validations' do From e62c5c35d7f540409958da02c78d82c8c42e9fff Mon Sep 17 00:00:00 2001 From: Maximilian Haack Date: Sun, 14 Feb 2021 16:49:57 -0500 Subject: [PATCH 15/17] Add Ruby 3.0 to test matrix (#39) * Add Ruby 3.0 to test matrix * Exclude Ruby 3 + Rails 5 Rails 5 doesn't support Ruby 3 --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbccaef..281a9dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,11 +8,13 @@ jobs: strategy: matrix: - ruby: [2.4, 2.7] + ruby: [2.4, 2.7, '3.0'] rails: ['5', '6.0', '6'] exclude: - ruby: 2.4 rails: 6 + - ruby: '3.0' + rails: 5 steps: - uses: actions/checkout@v2 From 7cd36989c9e4f708071fdf95b70aa7db6c7ea0bc Mon Sep 17 00:00:00 2001 From: kalle saas Date: Tue, 16 Feb 2021 15:11:23 +0100 Subject: [PATCH 16/17] always call jsonapi_page_size method on pagination enabled requests (#40) * always call jsonapi_page_size method on pagination enabled requests pass the per_page_param to the jsonapi_page_size method * pass pagination to jsonapi_page_size and handle string-to-int conversion in jsonapi_page_size * update readme to reflect changes * fix woring --- README.md | 8 +++++--- lib/jsonapi/pagination.rb | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index fe94452..5e86183 100644 --- a/README.md +++ b/README.md @@ -308,12 +308,14 @@ use the `jsonapi_pagination_meta` method: ``` -If you want to change the default number of items per page, use the +If you want to change the default number of items per page or define a custom logic to handle page size, use the `jsonapi_page_size` method: ```ruby - def jsonapi_page_size - 30 + def jsonapi_page_size(pagination_params) + per_page = pagination_params[:size].to_f.to_i + per_page = 30 if per_page > 30 + per_page end ``` ### Deserialization diff --git a/lib/jsonapi/pagination.rb b/lib/jsonapi/pagination.rb index 03ae22d..a98d149 100644 --- a/lib/jsonapi/pagination.rb +++ b/lib/jsonapi/pagination.rb @@ -96,8 +96,7 @@ def jsonapi_pagination_meta(resources) # @return [Array] with the offset, limit and the current page number def jsonapi_pagination_params pagination = params[:page].try(:slice, :number, :size) || {} - per_page = pagination[:size].to_f.to_i - per_page = jsonapi_page_size if per_page < 1 + per_page = jsonapi_page_size(pagination) num = [1, pagination[:number].to_f.to_i].max [(num - 1) * per_page, per_page, num] @@ -105,9 +104,19 @@ def jsonapi_pagination_params # Retrieves the default page size # + # @param per_page_param [Hash] opts the paginations params + # @option opts [String] :number the page number requested + # @option opts [String] :size the page size requested + # # @return [Integer] - def jsonapi_page_size - self.class.const_get(:JSONAPI_PAGE_SIZE).to_i + def jsonapi_page_size(pagination_params) + per_page = pagination_params[:size].to_f.to_i + + return self.class + .const_get(:JSONAPI_PAGE_SIZE) + .to_i if per_page < 1 + + per_page end # Fallback to Rack's parsed query string when Rails is not available From a28f6d4a9f8545a8dcf4536f48f838a015df499c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Wed, 17 Feb 2021 11:32:12 +0000 Subject: [PATCH 17/17] Version bump. --- lib/jsonapi/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jsonapi/version.rb b/lib/jsonapi/version.rb index 7134ef7..80870e2 100644 --- a/lib/jsonapi/version.rb +++ b/lib/jsonapi/version.rb @@ -1,3 +1,3 @@ module JSONAPI - VERSION = '1.6.0' + VERSION = '1.7.0' end