Skip to content

Commit 1a3b21b

Browse files
chrisdpeterstiagopog
authored andcommitted
Add support for classes that include ActiveModel::Model (#46)
* Add support for classes that include ActiveModel::Model * Refactor ActiveRecord/ActiveModel object detection in error formatter
1 parent 240f9ee commit 1a3b21b

File tree

6 files changed

+73
-1
lines changed

6 files changed

+73
-1
lines changed

lib/jsonapi/utils/response/formatters.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ def jsonapi_format(records, options = {})
1414
alias_method :jsonapi_serialize, :jsonapi_format
1515

1616
def jsonapi_format_errors(data)
17-
data = JSONAPI::Utils::Exceptions::ActiveRecord.new(data, @request.resource_klass, context) if data.is_a?(ActiveRecord::Base)
17+
data = JSONAPI::Utils::Exceptions::ActiveRecord.new(data, @request.resource_klass, context) if active_record_obj?(data)
1818
errors = data.respond_to?(:errors) ? data.errors : data
1919
JSONAPI::Utils::Support::Error.sanitize(errors).uniq
2020
end
2121

2222
private
2323

24+
def active_record_obj?(data)
25+
data.is_a?(ActiveRecord::Base)|| data.singleton_class.include?(ActiveModel::Model)
26+
end
27+
2428
def build_response_document(records, options)
2529
results = JSONAPI::OperationResults.new
2630

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
require 'spec_helper'
2+
3+
describe ProfileController, type: :controller do
4+
include_context 'JSON API headers'
5+
6+
let(:fields) { (ProfileResource.fields - %i(id)).map(&:to_s) }
7+
let(:resource) { Profile }
8+
let(:attributes) { { location: 'Springfield, USA' } }
9+
10+
let(:body) do
11+
{
12+
data: {
13+
type: 'profiles',
14+
id: '1234',
15+
attributes: attributes
16+
}
17+
}
18+
end
19+
20+
describe '#show' do
21+
it 'renders from ActiveModel::Model logic' do
22+
get :show
23+
expect(response).to have_http_status :ok
24+
expect(response).to have_primary_data('profiles')
25+
expect(response).to have_data_attributes(fields)
26+
end
27+
end
28+
29+
describe '#update' do
30+
it 'renders a 422 response' do
31+
patch :update, params: body
32+
expect(response).to have_http_status :unprocessable_entity
33+
expect(errors[0]['id']).to eq('location')
34+
expect(errors[0]['title']).to eq("Location can't be blank")
35+
expect(errors[0]['code']).to eq('100')
36+
expect(errors[0]['source']['pointer']).to eq('/data/attributes/location')
37+
end
38+
end
39+
end

spec/spec_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class TestApp < Rails::Application
9595
jsonapi_resources :posts, shallow: true
9696
end
9797

98+
jsonapi_resource :profile
99+
98100
patch :update_with_error_on_base, to: 'posts#update_with_error_on_base'
99101

100102
get :index_with_hash, to: 'posts#index_with_hash'

spec/support/controllers.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,20 @@ def update_relationships(user)
125125
end
126126
end
127127
end
128+
129+
class ProfileController < BaseController
130+
# GET /profile
131+
def show
132+
profile = Profile.new
133+
profile.id = '1234'
134+
profile.location = 'Springfield, USA'
135+
jsonapi_render json: profile
136+
end
137+
138+
# PATCH /profile
139+
def update
140+
profile = Profile.new
141+
profile.valid?
142+
jsonapi_render_errors json: profile, status: :unprocessable_entity
143+
end
144+
end

spec/support/models.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,9 @@ class Category < ActiveRecord::Base
5555
has_many :posts
5656
validates :title, presence: true
5757
end
58+
59+
class Profile
60+
include ActiveModel::Model
61+
attr_accessor :id, :location
62+
validates :location, presence: true
63+
end

spec/support/resources.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ def full_name
2626
"#{@model.first_name} #{@model.last_name}"
2727
end
2828
end
29+
30+
class ProfileResource < JSONAPI::Resource
31+
attribute :location
32+
end

0 commit comments

Comments
 (0)