Skip to content

Commit

Permalink
Remove error model (#63)
Browse files Browse the repository at this point in the history
* Use ruby 2.7

* Rework error model dependency

* Update rubocop

* Add upgrading note

* Correct ENV name

* Fix options

* Drop support for old rails versions
  • Loading branch information
mkon authored Apr 13, 2021
1 parent 34aec3b commit 2c6aa3c
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 79 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
activesupport: ['5.2', '6.0', '6.1']
activesupport: ['6.1']

steps:
- uses: actions/checkout@v1
Expand Down
8 changes: 4 additions & 4 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
AllCops:
TargetRubyVersion: 2.6
NewCops: enable

Layout/AlignHash:
Layout/HashAlignment:
EnforcedColonStyle: table
Layout/LineLength:
Max: 120
Layout/SpaceInsideHashLiteralBraces:
EnforcedStyle: no_space

Lint/AssignmentInCondition:
Enabled: false

Metrics/LineLength:
Max: 120

Style/ClassAndModuleChildren:
Enabled: false
Style/ConditionalAssignment:
Expand Down
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.6.4
2.7.2
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ group :development, :test do
gem 'byebug'
end

if (version = ENV['RAILS'])
if (version = ENV['ACTIVESUPPORT'])
gem 'activesupport', "~> #{version}.0"
end
8 changes: 8 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 0.1 -> 0.2

Some changes to make writing serializers for non-active record objects easier.

* ErrorSerializer class was renamed to EachSerializer
* EachSerializer's initializer now accepts 3 parameters instead of 2. The first
parameter is now the resource
* The included error model was removed
9 changes: 5 additions & 4 deletions invalid_model-serializer.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@ $LOAD_PATH.push File.expand_path('lib', __dir__)
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = 'invalid_model-serializer'
s.version = ENV.fetch 'VERSION', '0.1.4'
s.version = ENV.fetch 'VERSION', '0.2.0'
s.authors = ['mkon']
s.email = ['[email protected]']
s.homepage = 'https://github.com/mkon/invalid_model-serializer'
s.summary = 'Serialize models with validation errors to json-api errors.'
s.license = 'MIT'
s.required_ruby_version = '~> 2.6'

s.files = Dir['{app,config,db,lib}/**/*', 'LICENSE', 'README.md']

s.add_dependency 'activesupport', '>= 5.0', '< 7'
s.add_dependency 'activesupport', '>= 6.1', '< 7'

s.add_development_dependency 'activemodel', '>= 5.0', '< 7'
s.add_development_dependency 'json_spec', '~> 1.1'
s.add_development_dependency 'rspec', '~> 3.7'
s.add_development_dependency 'rubocop', '0.76.0'
s.add_development_dependency 'rubocop-rspec', '1.36.0'
s.add_development_dependency 'rubocop', '1.11.0'
s.add_development_dependency 'rubocop-rspec', '2.2.0'
s.add_development_dependency 'simplecov', '~> 0.16'
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module InvalidModel
class ErrorSerializer
def initialize(error, options = {})
class EachSerializer
def initialize(resource, error, options = {})
@resource = resource
@error = error
@options = options
end
Expand All @@ -9,21 +10,22 @@ def serializable_hash
{
code: code,
detail: detail,
meta: meta.presence,
meta: meta,
source: source,
status: status
}.compact
end

private

attr_reader :error
attr_reader :error, :resource

delegate :attribute, :detail, :meta, :model_name, :type, to: :error
delegate :attribute, :type, to: :error
delegate :errors, :model_name, to: :resource

def code
if @options[:code]&.respond_to?(:call)
@options[:code].call error
if @options[:code].respond_to?(:call)
@options[:code].call resource, error
elsif @options[:code]
@options[:code]
else
Expand All @@ -35,6 +37,14 @@ def code_format
@options[:code_format] || InvalidModel::Serializer.default_code_format
end

def detail
errors.full_message(attribute, errors.generate_message(attribute, type, error.options))
end

def meta
error.options.presence
end

def source
return @options[:source] if @options.key?(:source)
return if attribute == :base
Expand Down
24 changes: 0 additions & 24 deletions lib/invalid_model/error.rb

This file was deleted.

29 changes: 8 additions & 21 deletions lib/invalid_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
require 'active_support'

module InvalidModel
autoload :Error, 'invalid_model/error'
autoload :ErrorSerializer, 'invalid_model/error_serializer'
autoload :Error, 'invalid_model/error'
autoload :EachSerializer, 'invalid_model/each_serializer'

class Serializer
include ActiveSupport::Configurable
Expand All @@ -17,30 +17,17 @@ def initialize(resource, options = {})
end

def serializable_hash
{
errors: serialized_errors
}
list = []
@resource.errors.each do |error|
list << each_serializer_klass.new(@resource, error, @options).serializable_hash
end
{errors: list}
end

private

def each_serializer_klass
@options[:each_serializer] || ErrorSerializer
end

def errors_object
@resource.errors
end

def errors_list
list = errors_object.details.map do |key, array|
array.map { |error| Error.from_hash(errors_object, key, error) }
end
list.flatten
end

def serialized_errors
errors_list.map { |error| each_serializer_klass.new(error, @options).serializable_hash }
@options[:each_serializer] || EachSerializer
end
end
end
2 changes: 2 additions & 0 deletions spec/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ RSpec/ExampleLength:
Enabled: false
RSpec/MultipleExpectations:
Enabled: false
RSpec/MultipleMemoizedHelpers:
Enabled: false
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
RSpec.describe InvalidModel::ErrorSerializer do
subject(:hash) { described_class.new(error, options).serializable_hash }
RSpec.describe InvalidModel::EachSerializer do
subject(:hash) { described_class.new(resource, error, options).serializable_hash }

let(:json) { MultiJson.dump(hash) }
let(:resource) { DummyModel.new }
let(:error) do
instance_double(
InvalidModel::Error,
attribute: attribute,
type: type,
meta: meta,
detail: detail,
model_name: ActiveModel::Name.new(DummyModel)
ActiveModel::Error,
attribute: attribute,
type: type,
options: meta
)
end
let(:options) { {} }
let(:attribute) { :my_attribute }
let(:detail) { 'my detail' }
let(:type) { :my_type }
let(:attribute) { :code }
let(:type) { :invalid }
let(:meta) { {} }

it 'renders correctly' do
expect(json).to be_json_eql(
<<-JSON
{
"code": "validation_error/#{type}",
"detail": "#{detail}",
"detail": "Code is invalid",
"source": {
"pointer": "/data/attributes/#{attribute}"
},
Expand All @@ -45,15 +43,15 @@
let(:options) { {code_format: '%<model>s.validation_error/%<attribute>s/%<type>s'} }

it 'uses the new value' do
expect(hash[:code]).to eq 'dummy_model.validation_error/my_attribute/my_type'
expect(hash[:code]).to eq 'dummy_model.validation_error/code/invalid'
end
end

context 'when setting code as a proc' do
let(:options) { {code: ->(e) { "#{e.model_name.name}/#{e.type}" }} }
let(:options) { {code: ->(r, e) { "#{r.model_name}/#{e.type}" }} }

it 'uses the new value' do
expect(hash[:code]).to eq 'DummyModel/my_type'
expect(hash[:code]).to eq 'DummyModel/invalid'
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@

require_relative 'support/dummy_model'

I18n.load_path << Dir[File.expand_path('spec/support/locales') + '/*.yml']
I18n.load_path << Dir["#{File.expand_path('spec/support/locales')}/*.yml"]

0 comments on commit 2c6aa3c

Please sign in to comment.