From 9dea4ed921f9623553638f3189b246e1d3590d5d Mon Sep 17 00:00:00 2001 From: Tiago Guedes Date: Sat, 2 Jul 2016 22:30:00 -0300 Subject: [PATCH 1/8] Change protected methods to private --- README.md | 6 +++--- lib/jsonapi/utils.rb | 4 ++-- lib/jsonapi/utils/response/formatters.rb | 2 +- lib/jsonapi/utils/response/support.rb | 2 +- spec/support/controllers.rb | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f19d495..7080208 100644 --- a/README.md +++ b/README.md @@ -288,7 +288,7 @@ Finally, having inhirited `JSONAPI::Utils` methods from the `BaseController` we head :no_content end - protected + private def user_params params.require(:data).require(:attributes).permit(:first_name, :last_name, :admin) @@ -320,8 +320,8 @@ class PostsController < BaseController jsonapi_render_errors json: post, status: :unprocessable_entity end end - - protected + + private def post_params params.require(:data).require(:attributes).permit(:title, :body) diff --git a/lib/jsonapi/utils.rb b/lib/jsonapi/utils.rb index ae248bf..8d3bee0 100644 --- a/lib/jsonapi/utils.rb +++ b/lib/jsonapi/utils.rb @@ -6,8 +6,8 @@ module JSONAPI module Utils - include JSONAPI::Utils::Request - include JSONAPI::Utils::Response + include Request + include Response def self.included(base) if base.respond_to?(:before_action) diff --git a/lib/jsonapi/utils/response/formatters.rb b/lib/jsonapi/utils/response/formatters.rb index 21c6d65..4f1899b 100644 --- a/lib/jsonapi/utils/response/formatters.rb +++ b/lib/jsonapi/utils/response/formatters.rb @@ -19,7 +19,7 @@ def jsonapi_format_errors(data) JSONAPI::Utils::Support::Error.sanitize(errors).uniq end - protected + private def build_response_document(records, options) results = JSONAPI::OperationResults.new diff --git a/lib/jsonapi/utils/response/support.rb b/lib/jsonapi/utils/response/support.rb index 512e16c..5ce6c37 100644 --- a/lib/jsonapi/utils/response/support.rb +++ b/lib/jsonapi/utils/response/support.rb @@ -12,7 +12,7 @@ module Support include ::JSONAPI::Utils::Support::Pagination include ::JSONAPI::Utils::Support::Sort - protected + private def correct_media_type if response.body.size > 0 diff --git a/spec/support/controllers.rb b/spec/support/controllers.rb index 51336e2..4a83be4 100644 --- a/spec/support/controllers.rb +++ b/spec/support/controllers.rb @@ -48,7 +48,7 @@ def create end end - protected + private def post_params params.require(:data).require(:attributes).permit(:title, :body) @@ -100,7 +100,7 @@ def update end end - protected + private def user_params params.require(:data).require(:attributes).permit(:first_name, :last_name, :admin) From bb52a0a1758420dfd5c7d0a74a8c5b1ddf146c73 Mon Sep 17 00:00:00 2001 From: Tiago Guedes Date: Sat, 2 Jul 2016 22:48:54 -0300 Subject: [PATCH 2/8] Add JSONAPI::Utils::Request#resource_params helper method --- lib/jsonapi/utils/request.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/jsonapi/utils/request.rb b/lib/jsonapi/utils/request.rb index 17b2bec..afb3be1 100644 --- a/lib/jsonapi/utils/request.rb +++ b/lib/jsonapi/utils/request.rb @@ -14,6 +14,13 @@ def setup_request def check_request @request.errors.blank? || jsonapi_render_errors(json: @request) end + + def resource_params + unless @request.operations.empty? + operation = @request.operations.find { |e| e.data[:attributes].present? } + operation.nil? ? {} : operation.data[:attributes] + end + end end end end From 7f12fbd6299258d683178ec218000906c4d23efa Mon Sep 17 00:00:00 2001 From: Tiago Guedes Date: Sat, 2 Jul 2016 23:33:49 -0300 Subject: [PATCH 3/8] Add JSONAPI::Utils::Request#relationship_params helper method --- lib/jsonapi/utils/request.rb | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/jsonapi/utils/request.rb b/lib/jsonapi/utils/request.rb index afb3be1..ee3a4fc 100644 --- a/lib/jsonapi/utils/request.rb +++ b/lib/jsonapi/utils/request.rb @@ -16,9 +16,27 @@ def check_request end def resource_params - unless @request.operations.empty? - operation = @request.operations.find { |e| e.data[:attributes].present? } - operation.nil? ? {} : operation.data[:attributes] + build_params_for(:resource) + end + + def relationship_params + build_params_for(:relationship) + end + + private + + def build_params_for(param_type) + return {} if @request.operations.empty? + + keys = %i(attributes to_one to_many) + operation = @request.operations.find { |e| e.data.keys & keys == keys } + + if operation.nil? + {} + elsif param_type == :relationship + operation.data.values_at(:has_one, :to_many).compact.reduce(&:merge) + else + operation.data[:attributes] end end end From a21aee70a5a899e7175545879774bf25435598fa Mon Sep 17 00:00:00 2001 From: Tiago Guedes Date: Sun, 3 Jul 2016 16:01:20 -0300 Subject: [PATCH 4/8] Write specs for (resource|relationship)_params helpers --- lib/jsonapi/utils/request.rb | 2 +- spec/controllers/posts_controller_spec.rb | 7 +++++-- spec/support/controllers.rb | 20 +++++--------------- spec/support/models.rb | 2 +- spec/support/resources.rb | 3 ++- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/lib/jsonapi/utils/request.rb b/lib/jsonapi/utils/request.rb index ee3a4fc..5e7bead 100644 --- a/lib/jsonapi/utils/request.rb +++ b/lib/jsonapi/utils/request.rb @@ -34,7 +34,7 @@ def build_params_for(param_type) if operation.nil? {} elsif param_type == :relationship - operation.data.values_at(:has_one, :to_many).compact.reduce(&:merge) + operation.data.values_at(:to_one, :to_many).compact.reduce(&:merge) else operation.data[:attributes] end diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 7930c1e..9d76e6f 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -20,8 +20,11 @@ let(:post_params) do { - data: { type: 'posts', attributes: attributes }, - relationships: { author: author_params } + data: { + type: 'posts', + attributes: attributes, + relationships: { author: author_params } + } } end diff --git a/spec/support/controllers.rb b/spec/support/controllers.rb index 4a83be4..f6c2a1d 100644 --- a/spec/support/controllers.rb +++ b/spec/support/controllers.rb @@ -1,4 +1,5 @@ require 'support/exceptions' +require 'pry' class BaseController < JSONAPI::ResourceController include JSONAPI::Utils @@ -36,7 +37,7 @@ def show_with_hash options: { model: Post, resource: ::V2::PostResource } end - # POST /users + # POST /posts def create post = Post.new(post_params) if post.save @@ -51,12 +52,7 @@ def create private def post_params - params.require(:data).require(:attributes).permit(:title, :body) - .merge(user_id: author_params[:id]) - end - - def author_params - params.require(:relationships).require(:author).require(:data).permit(:id) + resource_params.merge(user_id: relationship_params[:author]) end def load_user @@ -79,7 +75,7 @@ def show # POST /users def create - user = User.new(user_params) + user = User.new(resource_params) if user.save jsonapi_render json: user, status: :created else @@ -91,7 +87,7 @@ def create # PATCH /users/:id def update user = User.find(params[:id]) - if user.update(user_params) + if user.update(resource_params) jsonapi_render json: user else # Example of error rendering for exceptions or any object @@ -99,10 +95,4 @@ def update jsonapi_render_errors ::Exceptions::MyCustomError.new(user) end end - - private - - def user_params - params.require(:data).require(:attributes).permit(:first_name, :last_name, :admin) - end end diff --git a/spec/support/models.rb b/spec/support/models.rb index f8a6aad..556a7e0 100644 --- a/spec/support/models.rb +++ b/spec/support/models.rb @@ -27,5 +27,5 @@ class User < ActiveRecord::Base class Post < ActiveRecord::Base belongs_to :author, class_name: 'User', foreign_key: 'user_id' - validates :title, :body, presence: true + validates :title, :body, :author, presence: true end diff --git a/spec/support/resources.rb b/spec/support/resources.rb index 9288597..341ec47 100644 --- a/spec/support/resources.rb +++ b/spec/support/resources.rb @@ -1,6 +1,6 @@ class PostResource < JSONAPI::Resource attributes :title, :body - has_one :author, class_name: 'User', foreign_key: 'user_id' + has_one :author end module V2 @@ -9,6 +9,7 @@ class PostResource < ::PostResource; end class UserResource < JSONAPI::Resource attributes :first_name, :last_name, :full_name + attribute :full_name has_many :posts From a8b3ab4aaa93274dc3cb0b1185f77bc5012074a5 Mon Sep 17 00:00:00 2001 From: Tiago Guedes Date: Sun, 3 Jul 2016 16:12:11 -0300 Subject: [PATCH 5/8] Remove the "pry" require --- spec/support/controllers.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/support/controllers.rb b/spec/support/controllers.rb index f6c2a1d..96e3cd8 100644 --- a/spec/support/controllers.rb +++ b/spec/support/controllers.rb @@ -1,5 +1,4 @@ require 'support/exceptions' -require 'pry' class BaseController < JSONAPI::ResourceController include JSONAPI::Utils From 94a222bd48da4a00ae28ee8dc1b225967aa3f56a Mon Sep 17 00:00:00 2001 From: Tiago Guedes Date: Sun, 3 Jul 2016 23:14:45 -0300 Subject: [PATCH 6/8] Call JSONAPI::Utils::Request#jsonapi_request_handling before action --- lib/jsonapi/utils.rb | 2 +- lib/jsonapi/utils/request.rb | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/jsonapi/utils.rb b/lib/jsonapi/utils.rb index 8d3bee0..bf51814 100644 --- a/lib/jsonapi/utils.rb +++ b/lib/jsonapi/utils.rb @@ -11,7 +11,7 @@ module Utils def self.included(base) if base.respond_to?(:before_action) - base.before_action :setup_request, :check_request + base.before_action :jsonapi_request_handling end end end diff --git a/lib/jsonapi/utils/request.rb b/lib/jsonapi/utils/request.rb index 5e7bead..2674aa7 100644 --- a/lib/jsonapi/utils/request.rb +++ b/lib/jsonapi/utils/request.rb @@ -1,6 +1,11 @@ module JSONAPI module Utils module Request + def jsonapi_request_handling + setup_request + check_request + end + def setup_request @request ||= JSONAPI::Request.new( From 852e9001482813a222e5fe3ceaeef23b15981f37 Mon Sep 17 00:00:00 2001 From: Tiago Guedes Date: Mon, 4 Jul 2016 00:08:48 -0300 Subject: [PATCH 7/8] Use a copy of params to avoid errors with jsonapi-resources' default update action --- lib/jsonapi/utils/request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jsonapi/utils/request.rb b/lib/jsonapi/utils/request.rb index 2674aa7..e5bdd84 100644 --- a/lib/jsonapi/utils/request.rb +++ b/lib/jsonapi/utils/request.rb @@ -9,7 +9,7 @@ def jsonapi_request_handling def setup_request @request ||= JSONAPI::Request.new( - params, + params.dup, context: context, key_formatter: key_formatter, server_error_callbacks: (self.class.server_error_callbacks || []) From 7adeadbadd7ff2d7a793086d2a7b01adc005c214 Mon Sep 17 00:00:00 2001 From: Tiago Guedes Date: Mon, 4 Jul 2016 01:18:24 -0300 Subject: [PATCH 8/8] Write specs for the new helper methods --- spec/controllers/users_controller_spec.rb | 10 ++++++++++ spec/support/controllers.rb | 7 ++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 5e1aba5..1487f97 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -282,21 +282,31 @@ describe '#update' do let(:user) { User.first } + let(:post) { user.posts.first } let(:update_params) do user_params.tap do |params| params[:data][:id] = user.id params[:data][:attributes].merge!(first_name: 'Yukihiro') + params[:data][:relationships] = relationship_params params.merge!(id: user.id) end end + let(:relationship_params) do + { posts: { data: [{ id: post.id, type: "posts" }] } } + end + it 'update an existing user' do patch :update, update_params + expect(response).to have_http_status :ok expect(response).to have_primary_data('users') expect(response).to have_data_attributes(fields) expect(data['attributes']['first_name']).to eq(user_params[:data][:attributes][:first_name]) + + expect(user.reload.posts.count).to eq(1) + expect(user.posts.first).to eq(post) end context 'when resource was not found' do diff --git a/spec/support/controllers.rb b/spec/support/controllers.rb index cc9e563..6448141 100644 --- a/spec/support/controllers.rb +++ b/spec/support/controllers.rb @@ -86,7 +86,7 @@ def create # PATCH /users/:id def update user = User.find(params[:id]) - if user.update(resource_params) + if user.update(resource_params) && update_relationships(user) jsonapi_render json: user else # Example of error rendering for exceptions or any object @@ -97,7 +97,8 @@ def update private - def user_params - params.require(:data).require(:attributes).permit(:first_name, :last_name, :admin) + def update_relationships(user) + return user if relationship_params[:posts].blank? + user.posts = Post.where(id: relationship_params[:posts]) end end