From 5f1d879ffe42165f2cec06e235b066e3bea78ae4 Mon Sep 17 00:00:00 2001 From: Ismail Akbudak Date: Fri, 30 Apr 2021 11:30:40 +0300 Subject: [PATCH 1/5] Add ruby-version file --- .ruby-version | 1 + 1 file changed, 1 insertion(+) create mode 100644 .ruby-version diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..952f449 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.6.6 \ No newline at end of file From edbc9c4c9ed48d20ca53a1c25d1e8352a938eeee Mon Sep 17 00:00:00 2001 From: Ismail Akbudak Date: Fri, 30 Apr 2021 11:32:01 +0300 Subject: [PATCH 2/5] Fix broken spec --- spec/pagination_spec.rb | 138 +++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 53 deletions(-) diff --git a/spec/pagination_spec.rb b/spec/pagination_spec.rb index ec1c3c4..118cb69 100644 --- a/spec/pagination_spec.rb +++ b/spec/pagination_spec.rb @@ -20,12 +20,18 @@ .to eq( 'many' => true, 'pagination' => { - 'current' => 1, - 'records' => 0 + 'total_page' => 1, + 'total_count' => 0, } ) end + def query_str(parms, page: nil) + parms = parms.deep_merge(page: { number: page }) if page + + "?#{CGI.unescape(parms.to_query)}" + end + context 'with users' do let(:first_user) { create_user } let(:second_user) { create_user } @@ -41,14 +47,14 @@ expect(response_json['data'][1]).to have_id(second_user.id.to_s) expect(response_json['data'][2]).to have_id(first_user.id.to_s) - expect(response_json).to have_link('self') - expect(response_json).not_to have_link(:prev) - expect(response_json).not_to have_link(:next) - expect(response_json).not_to have_link(:first) - expect(response_json).not_to have_link(:last) + expect(response_json).to have_link('current') + expect(response_json).to have_link(:prev) + expect(response_json).to have_link(:next) + expect(response_json).to have_link(:first) + expect(response_json).to have_link(:last) - expect(URI.parse(response_json['links']['self']).query) - .to eq(CGI.unescape(params.to_query)) + expect(URI.parse(response_json['links']['current']).query) + .to eq(CGI.unescape(params.deep_merge(page: { number: 1 }).to_query)) end context 'on page 2 out of 3' do @@ -70,13 +76,16 @@ expect(response_json['data'][0]).to have_id(second_user.id.to_s) expect(response_json['meta']['pagination']).to eq( - 'current' => 2, - 'first' => 1, - 'prev' => 1, - 'next' => 3, - 'last' => 3, - 'records' => 3 + 'total_count'=> 3, + 'total_page'=> 3 ) + expect(response_json['links']).to eq( + 'current' => query_str(params), + 'first' => query_str(params, page: 1), + 'prev' => query_str(params, page: 1), + 'next' => query_str(params, page: 3), + 'last' => query_str(params, page: 3), + ) end end @@ -86,25 +95,28 @@ expect(response_json['data'][0]).to have_id(second_user.id.to_s) expect(response_json['meta']['pagination']).to eq( - 'current' => 2, - 'first' => 1, - 'prev' => 1, - 'next' => 3, - 'last' => 3, - 'records' => 3 + 'total_count'=> 3, + 'total_page'=> 3 + ) + expect(response_json['links']).to eq( + 'current' => query_str(params), + 'first' => query_str(params, page: 1), + 'prev' => query_str(params, page: 1), + 'next' => query_str(params, page: 3), + 'last' => query_str(params, page: 3), ) - expect(response_json).to have_link(:self) + expect(response_json).to have_link(:current) expect(response_json).to have_link(:prev) expect(response_json).to have_link(:first) expect(response_json).to have_link(:next) expect(response_json).to have_link(:last) qry = CGI.unescape(params.to_query) - expect(URI.parse(response_json['links']['self']).query).to eq(qry) + expect(URI.parse(response_json['links']['current']).query).to eq(qry) qry = CGI.unescape(params.deep_merge(page: { number: 2 }).to_query) - expect(URI.parse(response_json['links']['self']).query).to eq(qry) + expect(URI.parse(response_json['links']['current']).query).to eq(qry) qry = CGI.unescape(params.deep_merge(page: { number: 1 }).to_query) expect(URI.parse(response_json['links']['prev']).query).to eq(qry) @@ -128,19 +140,24 @@ expect(response_json['data'].size).to eq(1) expect(response_json['meta']['pagination']).to eq( - 'current' => 3, - 'first' => 1, - 'prev' => 2, - 'records' => 3 + 'total_count'=> 3, + 'total_page'=> 3 + ) + expect(response_json['links']).to eq( + 'current' => query_str(params), + 'first' => query_str(params, page: 1), + 'prev' => query_str(params, page: 2), + 'next' => nil, + 'last' => query_str(params, page: 3), ) - expect(response_json).to have_link(:self) + expect(response_json).to have_link(:current) expect(response_json).to have_link(:prev) expect(response_json).to have_link(:first) - expect(response_json).not_to have_link(:next) - expect(response_json).not_to have_link(:last) + expect(response_json).to have_link(:next) + expect(response_json).to have_link(:last) - expect(URI.parse(response_json['links']['self']).query) + expect(URI.parse(response_json['links']['current']).query) .to eq(CGI.unescape(params.to_query)) qry = CGI.unescape(params.deep_merge(page: { number: 2 }).to_query) @@ -168,10 +185,15 @@ expect(response_json['data'].size).to eq(0) expect(response_json['meta']['pagination']).to eq( - 'current' => 5, - 'first' => 1, - 'prev' => 4, - 'records' => 3 + 'total_count'=> 3, + 'total_page'=> 3 + ) + expect(response_json['links']).to eq( + 'current' => query_str(params), + 'first' => query_str(params, page: 1), + 'prev' => query_str(params, page: 4), + 'next' => nil, + 'last' => query_str(params, page: 3), ) end end @@ -181,19 +203,24 @@ expect(response_json['data'].size).to eq(0) expect(response_json['meta']['pagination']).to eq( - 'current' => 5, - 'first' => 1, - 'prev' => 4, - 'records' => 3 + 'total_count'=> 3, + 'total_page'=> 3 + ) + expect(response_json['links']).to eq( + 'current' => query_str(params), + 'first' => query_str(params, page: 1), + 'prev' => query_str(params, page: 4), + 'next' => nil, + 'last' => query_str(params, page: 3), ) - expect(response_json).to have_link(:self) + expect(response_json).to have_link(:current) expect(response_json).to have_link(:prev) expect(response_json).to have_link(:first) - expect(response_json).not_to have_link(:next) - expect(response_json).not_to have_link(:last) + expect(response_json).to have_link(:next) + expect(response_json).to have_link(:last) - expect(URI.parse(response_json['links']['self']).query) + expect(URI.parse(response_json['links']['current']).query) .to eq(CGI.unescape(params.to_query)) qry = CGI.unescape(params.deep_merge(page: { number: 4 }).to_query) @@ -207,7 +234,7 @@ context 'on page 1 out of 3' do let(:params) do { - page: { size: 1 }, + page: { size: 1, number: 1 }, sort: '-created_at' } end @@ -218,19 +245,24 @@ expect(response_json['data'][0]).to have_id(third_user.id.to_s) expect(response_json['meta']['pagination']).to eq( - 'current' => 1, - 'next' => 2, - 'last' => 3, - 'records' => 3 + 'total_count' => 3, + 'total_page' => 3, + ) + expect(response_json['links']).to eq( + 'current' => query_str(params), + 'first' => query_str(params, page: 1), + 'prev' => nil, + 'next' => query_str(params, page: 2), + 'last' => query_str(params, page: 3), ) - expect(response_json).not_to have_link(:prev) - expect(response_json).not_to have_link(:first) + expect(response_json).to have_link(:prev) + expect(response_json).to have_link(:first) expect(response_json).to have_link(:next) - expect(response_json).to have_link(:self) + expect(response_json).to have_link(:current) expect(response_json).to have_link(:last) - expect(URI.parse(response_json['links']['self']).query) + expect(URI.parse(response_json['links']['current']).query) .to eq(CGI.unescape(params.to_query)) qry = CGI.unescape(params.deep_merge(page: { number: 2 }).to_query) From 9668beab5053dbbd2472cb23a58b0d87ce0cb735 Mon Sep 17 00:00:00 2001 From: Ismail Akbudak Date: Fri, 30 Apr 2021 11:32:30 +0300 Subject: [PATCH 3/5] Add serializer_class parameter --- README.md | 16 +++++++++++++--- lib/jsonapi/rails.rb | 12 +++++++++--- spec/dummy.rb | 11 +++++++++-- spec/fetching_spec.rb | 17 +++++++++++++++++ 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5e86183..9e5818d 100644 --- a/README.md +++ b/README.md @@ -103,10 +103,20 @@ Please follow the [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` +To provide a different naming scheme use `serializer_class` parameter or implement the `jsonapi_serializer_class` method in your resource or application controller. -Here's an example: +Here's an example for `serializer_class` parameter: +```ruby +class CustomNamingController < ActionController::Base + def index + render jsonapi: Model.all, + serializer_class: MySerializer + end +end +``` + +Here's an example for `jsonapi_serializer_class` method: ```ruby class CustomNamingController < ActionController::Base @@ -287,7 +297,7 @@ class MyController < ActionController::Base def index jsonapi_paginate(Model.all) do |paginated| - render jsonapi: paginated + render jsonapi_paginate: paginated end end diff --git a/lib/jsonapi/rails.rb b/lib/jsonapi/rails.rb index 4ac4f10..3adf4b5 100644 --- a/lib/jsonapi/rails.rb +++ b/lib/jsonapi/rails.rb @@ -56,7 +56,9 @@ def self.add_errors_renderer! errors = [] model = resource.instance_variable_get('@base') - if respond_to?(:jsonapi_serializer_class, true) + if options[:serializer_class] + model_serializer = options[:serializer_class] + elsif respond_to?(:jsonapi_serializer_class, true) model_serializer = jsonapi_serializer_class(model, false) else model_serializer = JSONAPI::Rails.serializer_class(model, false) @@ -114,7 +116,9 @@ def self.add_renderer! options[opt] ||= send(method_name) if respond_to?(method_name, true) end - if respond_to?(:jsonapi_serializer_class, true) + if options[:serializer_class] + serializer_class = options[:serializer_class] + elsif respond_to?(:jsonapi_serializer_class, true) serializer_class = jsonapi_serializer_class(resource, many) else serializer_class = JSONAPI::Rails.serializer_class(resource, many) @@ -143,7 +147,9 @@ def self.add_renderer! options[opt] ||= send(method_name) if respond_to?(method_name, true) end - if respond_to?(:jsonapi_serializer_class, true) + if options[:serializer_class] + serializer_class = options[:serializer_class] + elsif respond_to?(:jsonapi_serializer_class, true) serializer_class = jsonapi_serializer_class(resource, many) else serializer_class = JSONAPI::Rails.serializer_class(resource, many) diff --git a/spec/dummy.rb b/spec/dummy.rb index 6f0c434..14c66d5 100644 --- a/spec/dummy.rb +++ b/spec/dummy.rb @@ -62,6 +62,12 @@ class UserSerializer end end +class MyUserSerializer < UserSerializer + attribute :full_name do |object, _| + "#{object.first_name} #{object.last_name}" + end +end + class Dummy < Rails::Application secrets.secret_key_base = '_' config.hosts << 'www.example.com' if config.respond_to?(:hosts) @@ -91,14 +97,15 @@ def index result = filtered.result if params[:sort].to_s.include?('notes_quantity') - render jsonapi: result.group('id').to_a + render jsonapi_paginate: result.group('id').to_a return end result = result.to_a if params[:as_list] jsonapi_paginate(result) do |paginated| - render jsonapi: paginated + render jsonapi_paginate: paginated, + serializer_class: MyUserSerializer end end end diff --git a/spec/fetching_spec.rb b/spec/fetching_spec.rb index a5382e7..98c7d27 100644 --- a/spec/fetching_spec.rb +++ b/spec/fetching_spec.rb @@ -34,6 +34,23 @@ end end + context 'returns customers and full name' do + let(:params) do + { fields: { full_name: true } } + end + + it do + expect(response).to have_http_status(:ok) + expect(response_json['data'].size).to eq(users.size) + + response_json['data'].each do |item| + user = users.detect { |u| u.id == item['id'].to_i } + expect(item).to have_attribute('full_name') + .with_value("#{user.first_name} #{user.last_name}") + end + end + end + context 'returns customers included and sparse fields' do let(:params) do { From 99b4c96390132afc9618f821403c89290182b095 Mon Sep 17 00:00:00 2001 From: Ismail Akbudak Date: Fri, 30 Apr 2021 11:50:10 +0300 Subject: [PATCH 4/5] Remove ruby 3.0 from 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 281a9dd..79800a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - ruby: [2.4, 2.7, '3.0'] + ruby: [2.4, 2.7] # do not support '3.0' for now rails: ['5', '6.0', '6'] exclude: - ruby: 2.4 From 9a4e66d01501586dd5498af9b8d8505a547e43b6 Mon Sep 17 00:00:00 2001 From: Ismail Akbudak Date: Fri, 30 Apr 2021 11:52:25 +0300 Subject: [PATCH 5/5] Revert ruby 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 79800a3..281a9dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - ruby: [2.4, 2.7] # do not support '3.0' for now + ruby: [2.4, 2.7, '3.0'] rails: ['5', '6.0', '6'] exclude: - ruby: 2.4