mirror of
https://github.com/samsonjs/grape-active_model_serializers.git
synced 2026-03-25 08:45:55 +00:00
Compare commits
34 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c985c86410 | |||
| 55f3861ae3 | |||
| af29f9c76e | |||
| 7ca250a305 | |||
| 61673fe322 | |||
| 26767f5fac | |||
| 6f1e4037bc | |||
|
|
cce31fe187 | ||
| 7f759b6560 | |||
| 1a1c8b8173 | |||
| 9941241efc | |||
|
|
6ca5a7c5cf | ||
| b609ebc639 | |||
| dcc17a065d | |||
| 0da8ef5bd3 | |||
| 0a11b5d101 | |||
| 096fd41c11 | |||
| 7e58753b76 | |||
|
|
eb200812c8 | ||
|
|
a8ecfa3daf | ||
|
|
7e9c064f88 | ||
|
|
791c1b0f5e | ||
|
|
7670d9aed7 | ||
|
|
1995ba4676 | ||
|
|
fcb4c3a8c5 | ||
|
|
27ad60099e | ||
|
|
003e69d2bb | ||
|
|
dc01b70f26 | ||
|
|
03af2a385a | ||
|
|
cea5cf9d3e | ||
|
|
c5d7a8b071 | ||
|
|
4b7a08fecb | ||
|
|
8b8da16ffe | ||
|
|
b2654190c1 |
26 changed files with 450 additions and 128 deletions
38
.github/workflows/ci.yml
vendored
Normal file
38
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
name: CI
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
danger:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 4.0.0
|
||||
- name: Install dependencies
|
||||
run: bundle install --jobs 4 --retry 3
|
||||
- name: Run Danger
|
||||
run: |
|
||||
# the token is public, has public_repo scope and belongs to the grape-bot user owned by @dblock, this is ok
|
||||
TOKEN=$(echo -n Z2hwX2lYb0dPNXNyejYzOFJyaTV3QUxUdkNiS1dtblFwZTFuRXpmMwo= | base64 --decode)
|
||||
DANGER_GITHUB_API_TOKEN=$TOKEN bundle exec danger --verbose
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
ruby-version: [4.0.0, 3.4.8, 3.3.10, 3.2.9]
|
||||
grape-version: ['~> 3.0.0', '~> 2.3.0']
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version }}
|
||||
- name: Install dependencies
|
||||
run: bundle install --jobs 4 --retry 3
|
||||
env:
|
||||
GRAPE_VERSION: ${{ matrix.grape-version }}
|
||||
- name: Run tests
|
||||
run: bundle exec rake
|
||||
env:
|
||||
GRAPE_VERSION: ${{ matrix.grape-version }}
|
||||
|
|
@ -4,6 +4,10 @@ AllCops:
|
|||
Exclude:
|
||||
- Guardfile
|
||||
- grape-active_model_serializers.gemspec
|
||||
NewCops: enable
|
||||
|
||||
Style/BlockDelimiters:
|
||||
Enabled: false
|
||||
|
||||
Style/FrozenStringLiteralComment:
|
||||
Enabled: false
|
||||
|
|
|
|||
|
|
@ -1,20 +1,71 @@
|
|||
# This configuration was generated by `rubocop --auto-gen-config`
|
||||
# on 2015-01-13 18:47:14 -0500 using RuboCop version 0.28.0.
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config`
|
||||
# on 2018-03-14 14:59:23 -0400 using RuboCop version 0.53.0.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 25
|
||||
# Configuration parameters: AllowURI, URISchemes.
|
||||
Metrics/AbcSize:
|
||||
Max: 20
|
||||
# Offense count: 1
|
||||
# Configuration parameters: Include.
|
||||
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
|
||||
Bundler/DuplicatedGem:
|
||||
Exclude:
|
||||
- 'Gemfile'
|
||||
|
||||
# Offense count: 7
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
# Offense count: 1
|
||||
Metrics/AbcSize:
|
||||
Max: 18
|
||||
|
||||
# Offense count: 23
|
||||
# Configuration parameters: CountComments, ExcludedMethods.
|
||||
Metrics/BlockLength:
|
||||
Max: 133
|
||||
|
||||
# Offense count: 1
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 9
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/MethodLength:
|
||||
Max: 15
|
||||
|
||||
# Offense count: 1
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 10
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: Exclude.
|
||||
Style/FileName:
|
||||
Enabled: false
|
||||
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
|
||||
# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
|
||||
Naming/FileName:
|
||||
Exclude:
|
||||
- 'lib/grape-active_model_serializers.rb'
|
||||
- 'spec/grape-active_model_serializers_spec.rb'
|
||||
|
||||
# Offense count: 5
|
||||
Style/Documentation:
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'test/**/*'
|
||||
- 'lib/grape-active_model_serializers/endpoint_extension.rb'
|
||||
- 'lib/grape-active_model_serializers/error_formatter.rb'
|
||||
- 'lib/grape-active_model_serializers/formatter.rb'
|
||||
- 'lib/grape-active_model_serializers/options_builder.rb'
|
||||
- 'lib/grape-active_model_serializers/serializer_resolver.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: MinBodyLength.
|
||||
Style/GuardClause:
|
||||
Exclude:
|
||||
- 'lib/grape-active_model_serializers/serializer_resolver.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
||||
# URISchemes: http, https
|
||||
Layout/LineLength:
|
||||
Max: 87
|
||||
|
||||
Lint/ConstantDefinitionInBlock:
|
||||
Exclude:
|
||||
- spec/integration/sequel_spec.rb
|
||||
|
|
|
|||
38
.travis.yml
38
.travis.yml
|
|
@ -1,38 +0,0 @@
|
|||
language: ruby
|
||||
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- rvm: 2.3.1
|
||||
script:
|
||||
- bundle exec danger
|
||||
- rvm: 2.3.1
|
||||
env: GRAPE_VERSION=0.8.0
|
||||
- rvm: 2.3.1
|
||||
env: GRAPE_VERSION=0.9.0
|
||||
- rvm: 2.3.1
|
||||
env: GRAPE_VERSION=0.10.1
|
||||
- rvm: 2.3.1
|
||||
env: GRAPE_VERSION=0.12.0
|
||||
- rvm: 2.3.1
|
||||
env: GRAPE_VERSION=0.13.0
|
||||
- rvm: 2.3.1
|
||||
env: GRAPE_VERSION=0.14.0
|
||||
- rvm: 2.3.1
|
||||
env: GRAPE_VERSION=0.15.0
|
||||
- rvm: 2.3.1
|
||||
env: GRAPE_VERSION=0.16.2
|
||||
- rvm: 2.3.1
|
||||
env: GRAPE_VERSION=HEAD
|
||||
- rvm: 2.3.0
|
||||
- rvm: 2.2.5
|
||||
- rvm: rbx-2
|
||||
- rvm: jruby-19mode
|
||||
- rvm: ruby-head
|
||||
- rvm: jruby-head
|
||||
allow_failures:
|
||||
- rvm: rbx-2
|
||||
- rvm: jruby-19mode
|
||||
- rvm: ruby-head
|
||||
- rvm: jruby-head
|
||||
32
CHANGELOG.md
32
CHANGELOG.md
|
|
@ -1,17 +1,31 @@
|
|||
## Changelog
|
||||
|
||||
### 1.5.2 (Next)
|
||||
### 2.0.2 (Next)
|
||||
|
||||
* Your contribution here.
|
||||
|
||||
### 1.5.1 (April 25, 2017)
|
||||
### 2.0.1 (2025/12/08)
|
||||
|
||||
* [#92](https://github.com/ruby-grape/grape-active_model_serializers/pull/92): Fix: accept nil serializer - [@mateusnava](https://github.com/mateusnava).
|
||||
* [#100](https://github.com/ruby-grape/grape-active_model_serializers/pull/100): Fix compatibility with Grape 3.0 and test in CI - [@samsonjs](https://github.com/samsonjs).
|
||||
|
||||
### 2.0.0 (2025/06/02)
|
||||
|
||||
* [#96](https://github.com/ruby-grape/grape-active_model_serializers/pull/96): Add compatibility for Grape 2.3 - [@samsonjs](https://github.com/samsonjs).
|
||||
* [#98](https://github.com/ruby-grape/grape-active_model_serializers/pull/98): Out with Travis CI, in with GitHub Actions - [@samsonjs](https://github.com/samsonjs).
|
||||
|
||||
### 1.5.2 (2018/03/14)
|
||||
|
||||
* [#76](https://github.com/ruby-grape/grape-active_model_serializers/pull/76): Add custom error formatter - [@xn](https://github.com/xn).
|
||||
|
||||
### 1.5.1 (2017/04/25)
|
||||
|
||||
* [#74](https://github.com/ruby-grape/grape-active_model_serializers/pull/74): Add support for Sequel - [@drn](https://github.com/drn).
|
||||
* [#73](https://github.com/ruby-grape/grape-active_model_serializers/pull/73): Ensure all AMS options are passed through - [@drn](https://github.com/drn).
|
||||
* [#65](https://github.com/ruby-grape/grape-active_model_serializers/pull/65): Added Danger, PR linter - [@dblock](https://github.com/dblock).
|
||||
* [#63](https://github.com/ruby-grape/grape-active_model_serializers/pull/63): Pass adapter options through render - [@drn](https://github.com/drn).
|
||||
|
||||
### 1.5.0 (August 24, 2016)
|
||||
### 1.5.0 (2016/08/24)
|
||||
|
||||
* [#61](https://github.com/ruby-grape/grape-active_model_serializers/pull/61): Adds support for collection serializers - [@drn](https://github.com/drn).
|
||||
* [#60](https://github.com/ruby-grape/grape-active_model_serializers/pull/60): Namespace serializer inference - [@drn](https://github.com/drn).
|
||||
|
|
@ -19,22 +33,22 @@
|
|||
* [#57](https://github.com/ruby-grape/grape-active_model_serializers/pull/57): Solve line length linter issues - [@drn](https://github.com/drn).
|
||||
* [#54](https://github.com/ruby-grape/grape-active_model_serializers/pull/54): Adding support for ASM v0.10. Drops support for ASM v0.9 - [@drn](https://github.com/drn).
|
||||
|
||||
### 1.4.0 (July 14, 2016)
|
||||
### 1.4.0 (2016/07/14)
|
||||
|
||||
* [#49](https://github.com/ruby-grape/grape-active_model_serializers/pull/49): Adds support for active model serializer namespace - [@syntaxTerr0r](https://github.com/syntaxTerr0r).
|
||||
* [#36](https://github.com/ruby-grape/grape-active_model_serializers/pull/36), [#50](https://github.com/jrhe/grape-active_model_serializers/pull/50): Added support through Grape 0.16.x - [@dblock](https://github.com/dblock).
|
||||
|
||||
### v1.3.2 (February 27, 2015)
|
||||
### 1.3.2 (2015/02/27)
|
||||
|
||||
* [#40](https://github.com/ruby-grape/grape-active_model_serializers/pull/40): Use env to pass AMS meta around - [@dblock](https://github.com/dblock).
|
||||
* [#39](https://github.com/ruby-grape/grape-active_model_serializers/pull/39): Look for namespace and other options to configure serializers - [@jwkoelewijn](https://github.com/jwkoelewijn).
|
||||
|
||||
### v1.3.1 (November 20, 2014)
|
||||
### 1.3.1 (2014/11/20)
|
||||
|
||||
* [#30](https://github.com/ruby-grape/grape-active_model_serializers/pull/30): Read options from default_serializer_options - [@siong1987](https://github.com/siong1987).
|
||||
* [#24](https://github.com/ruby-grape/grape-active_model_serializers/pull/24): Makes it possible to use `current_user` within serializers - [@sonxurxo](https://github.com/sonxurxo).
|
||||
|
||||
### v1.2.1 (July 23, 2014)
|
||||
### 1.2.1 (2014/07/23)
|
||||
|
||||
* [#21](https://github.com/ruby-grape/grape-active_model_serializers/pull/21): Correctly fetch serialization scope - [@radanskoric](https://github.com/radanskoric).
|
||||
* [#18](https://github.com/ruby-grape/grape-active_model_serializers/pull/18): Added support for active model serializer 0.9.x - [@sbounmy](https://github.com/sbounmy).
|
||||
|
|
@ -44,12 +58,12 @@
|
|||
* [#12](https://github.com/ruby-grape/grape-active_model_serializers/pull/12): Added support for `current_user` - [@kpassapk](https://github.com/kpassapk).
|
||||
* [#11](https://github.com/ruby-grape/grape-active_model_serializers/pull/11): Fixed require path - [@schickling](https://github.com/schickling).
|
||||
|
||||
### v1.0.1 (September 9, 2013)
|
||||
### 1.0.1 (2013/09/09)
|
||||
|
||||
* [#6](https://github.com/ruby-grape/grape-active_model_serializers/pull/6): Conform to ActiveModel::Serializers way of determining array-ness - [@tfe](https://github.com/tfe).
|
||||
* [#4](https://github.com/ruby-grape/grape-active_model_serializers/pull/4): Support for namespace options and rely more on active_model_serializers - [@johnallen3d](https://github.com/johnallen3d).
|
||||
* [#1](https://github.com/ruby-grape/grape-active_model_serializers/pull/1): Fix: Grape::ActiveModelSerializers for models with compound names - [@george](https://github.com/george).
|
||||
|
||||
### v1.0.0
|
||||
### 1.0.0 (2013/09/09)
|
||||
|
||||
* Initial public release - [@jrhe](https://github.com/jrhe).
|
||||
|
|
|
|||
15
Gemfile
15
Gemfile
|
|
@ -2,7 +2,7 @@ source 'https://rubygems.org'
|
|||
|
||||
gemspec
|
||||
|
||||
case version = ENV['GRAPE_VERSION'] || '~> 0.10.0'
|
||||
case version = ENV['GRAPE_VERSION'] || '~> 3.0.0'
|
||||
when 'HEAD'
|
||||
gem 'grape', github: 'intridea/grape'
|
||||
else
|
||||
|
|
@ -10,7 +10,16 @@ else
|
|||
end
|
||||
|
||||
group :test do
|
||||
gem 'rack-test'
|
||||
gem 'ruby-grape-danger', '~> 0.2.0', require: false
|
||||
gem 'sequel', '~> 5.91', require: false
|
||||
gem 'sqlite3'
|
||||
gem 'sequel', '~> 4.37', require: false
|
||||
gem 'ruby-grape-danger', '~> 0.1.0', require: false
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem 'guard-rspec'
|
||||
gem 'listen', '~> 3.9.0'
|
||||
gem 'rake'
|
||||
gem 'rspec'
|
||||
gem 'rubocop', '1.75.7'
|
||||
end
|
||||
|
|
|
|||
36
README.md
36
README.md
|
|
@ -1,9 +1,29 @@
|
|||
# Table of Contents
|
||||
|
||||
- [Grape::ActiveModelSerializers](#grapeactivemodelserializers)
|
||||
- [Installation](#installation)
|
||||
- [Dependencies](#dependencies)
|
||||
- [Usage](#usage)
|
||||
- [Require grape-active_model_serializers](#require-grape-active_model_serializers)
|
||||
- [Tell your API to use Grape::Formatter::ActiveModelSerializers](#tell-your-api-to-use-grapeformatteractivemodelserializers)
|
||||
- [Writing Serializers](#writing-serializers)
|
||||
- [Serializers are inferred by active_record model names](#serializers-are-inferred-by-active_record-model-names)
|
||||
- [Array Roots](#array-roots)
|
||||
- [API Versioning](#api-versioning)
|
||||
- [Manually specifying serializer / adapter options](#manually-specifying-serializer--adapter-options)
|
||||
- [Custom Metadata](#custom-metadata)
|
||||
- [Default Serializer Options](#default-serializer-options)
|
||||
- [Current User](#current-user)
|
||||
- [Full Example](#full-example)
|
||||
- [Contributing](#contributing)
|
||||
- [History](#history)
|
||||
|
||||
# Grape::ActiveModelSerializers
|
||||
|
||||
Use [active_model_serializers](https://github.com/rails-api/active_model_serializers) with [Grape](https://github.com/intridea/grape)!
|
||||
|
||||
[](https://badge.fury.io/rb/grape-active_model_serializers)
|
||||
[](http://travis-ci.org/ruby-grape/grape-active_model_serializers) [](https://gemnasium.com/ruby-grape/grape-active_model_serializers) [](https://codeclimate.com/github/ruby-grape/grape-active_model_serializers)
|
||||
[](https://github.com/ruby-grape/grape-active_model_serializers/actions/workflows/ci.yml) [](https://codeclimate.com/github/ruby-grape/grape-active_model_serializers)
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
@ -17,9 +37,9 @@ See [UPGRADING](UPGRADING.md) if you're upgrading from a previous version.
|
|||
|
||||
## Dependencies
|
||||
|
||||
* >= Ruby v2.2
|
||||
* >= [grape](https://github.com/intridea/grape) v0.8.0
|
||||
* >= [active_model_serializers](https://github.com/rails-api/active_model_serializers) v0.10.0
|
||||
* >= Ruby v3.1
|
||||
* >= [grape](https://github.com/ruby-grape/grape) v2.3.0
|
||||
* >= [active_model_serializers](https://github.com/rails-api/active_model_serializers) v0.10.0
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
@ -36,6 +56,12 @@ require 'grape-active_model_serializers'
|
|||
class API < Grape::API
|
||||
format :json
|
||||
formatter :json, Grape::Formatter::ActiveModelSerializers
|
||||
|
||||
# Serializes errors with ActiveModel::Serializer::ErrorSerializer if an ActiveModel.
|
||||
# Serializer conforms to the adapter, ex: json, jsonapi.
|
||||
# So an error formatted with a jsonapi formatter would render as per:
|
||||
# http://jsonapi.org/format/#error-objects
|
||||
error_formatter :json, Grape::Formatter::ActiveModelSerializers
|
||||
end
|
||||
```
|
||||
|
||||
|
|
@ -277,4 +303,4 @@ See [CONTRIBUTING](CONTRIBUTING.md).
|
|||
|
||||
## History
|
||||
|
||||
Structured and based upon [grape-rabl](https://github.com/LTe/grape-rabl).
|
||||
Structured and based upon [grape-rabl](https://github.com/ruby-grape/grape-rabl).
|
||||
|
|
|
|||
70
RELEASING.md
Normal file
70
RELEASING.md
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
# Releasing Grape::ActiveModelSerializers
|
||||
|
||||
There're no particular rules about when to release grape-active_model_serializers. Release bug fixes frequently, features not so frequently and breaking API changes rarely.
|
||||
|
||||
### Release
|
||||
|
||||
Run tests, check that all tests succeed locally.
|
||||
|
||||
```
|
||||
bundle install
|
||||
rake
|
||||
```
|
||||
|
||||
Check that the last build succeeded in [GitHub Actions](https://github.com/ruby-grape/grape-active_model_serializers/actions/workflows/ci.yml) for all supported platforms.
|
||||
|
||||
Change "Next Release" in [CHANGELOG.md](CHANGELOG.md) to the new version.
|
||||
|
||||
```
|
||||
### 0.7.2 (2014/02/06)
|
||||
```
|
||||
|
||||
Remove the line with "Your contribution here.", since there will be no more contributions to this release.
|
||||
|
||||
Commit your changes.
|
||||
|
||||
```
|
||||
git add CHANGELOG.md lib/grape-active_model_serializers/version.rb
|
||||
git commit -m "Preparing for release, 0.7.2."
|
||||
git push origin master
|
||||
```
|
||||
|
||||
Release.
|
||||
|
||||
```
|
||||
$ rake release
|
||||
|
||||
grape-active_model_serializers 0.7.2 built to pkg/grape-active_model_serializers-0.7.2.gem.
|
||||
Tagged v0.7.2.
|
||||
Pushed git commits and tags.
|
||||
Pushed grape-active_model_serializers 0.7.2 to rubygems.org.
|
||||
```
|
||||
|
||||
### Prepare for the Next Version
|
||||
|
||||
Modify [lib/grape-active_model_serializers/version.rb](lib/grape-active_model_serializers/version.rb), increment the third number (eg. change `0.7.2` to `0.7.3`).
|
||||
|
||||
|
||||
```ruby
|
||||
module Grape
|
||||
module ActiveModelSerializers
|
||||
VERSION = '0.7.3'.freeze
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Add the next release to [CHANGELOG.md](CHANGELOG.md).
|
||||
|
||||
```
|
||||
#### 0.7.3 (Next)
|
||||
|
||||
* Your contribution here.
|
||||
```
|
||||
|
||||
Commit your changes.
|
||||
|
||||
```
|
||||
git add CHANGELOG.md lib/grape-active_model_serializers/version.rb
|
||||
git commit -m "Preparing for next development iteration, 0.7.3."
|
||||
git push origin master
|
||||
```
|
||||
3
Rakefile
Normal file → Executable file
3
Rakefile
Normal file → Executable file
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env rake
|
||||
|
||||
require 'bundler/gem_tasks'
|
||||
|
||||
require 'rspec/core'
|
||||
|
|
@ -11,4 +12,4 @@ end
|
|||
require 'rubocop/rake_task'
|
||||
RuboCop::RakeTask.new(:rubocop)
|
||||
|
||||
task default: [:rubocop, :spec]
|
||||
task default: %i[rubocop spec]
|
||||
|
|
|
|||
|
|
@ -16,13 +16,6 @@ Gem::Specification.new do |gem|
|
|||
gem.version = Grape::ActiveModelSerializers::VERSION
|
||||
gem.licenses = ['MIT']
|
||||
|
||||
gem.add_dependency 'grape', '>= 0.8.0'
|
||||
gem.add_dependency 'grape', '>= 2.3.0'
|
||||
gem.add_dependency 'active_model_serializers', '>= 0.10.0'
|
||||
|
||||
gem.add_development_dependency 'listen', '~> 3.0.7'
|
||||
gem.add_development_dependency 'rspec'
|
||||
gem.add_development_dependency 'rack-test'
|
||||
gem.add_development_dependency 'rake'
|
||||
gem.add_development_dependency 'guard-rspec'
|
||||
gem.add_development_dependency 'rubocop', '0.41.2'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
require 'active_model_serializers'
|
||||
require 'grape'
|
||||
require 'grape-active_model_serializers/endpoint_extension'
|
||||
require 'grape-active_model_serializers/error_formatter'
|
||||
require 'grape-active_model_serializers/formatter'
|
||||
require 'grape-active_model_serializers/serializer_resolver'
|
||||
require 'grape-active_model_serializers/options_builder'
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ module Grape
|
|||
def serialization_scope
|
||||
return unless _serialization_scope
|
||||
return unless respond_to?(_serialization_scope, true)
|
||||
|
||||
send(_serialization_scope)
|
||||
end
|
||||
end
|
||||
|
|
@ -50,12 +51,10 @@ module Grape
|
|||
resources
|
||||
end
|
||||
|
||||
def default_serializer_options
|
||||
end
|
||||
def default_serializer_options; end
|
||||
|
||||
def url_options
|
||||
end
|
||||
def url_options; end
|
||||
end
|
||||
|
||||
Endpoint.send(:include, EndpointExtension)
|
||||
Endpoint.include EndpointExtension
|
||||
end
|
||||
|
|
|
|||
51
lib/grape-active_model_serializers/error_formatter.rb
Normal file
51
lib/grape-active_model_serializers/error_formatter.rb
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
module Grape
|
||||
module ErrorFormatter
|
||||
class ActiveModelSerializers < Base
|
||||
class << self
|
||||
def call(message, backtrace, options = {}, env = nil, original_exception = nil)
|
||||
message = present(message, env) if respond_to?(:present)
|
||||
message = wrap_message(message)
|
||||
|
||||
rescue_options = options[:rescue_options] || {}
|
||||
if rescue_options[:backtrace] && backtrace && !backtrace.empty?
|
||||
message = message.merge(backtrace: backtrace)
|
||||
end
|
||||
if rescue_options[:original_exception] && original_exception
|
||||
message = message
|
||||
.merge(original_exception: original_exception.inspect)
|
||||
end
|
||||
if ::Grape.const_defined? :Json
|
||||
::Grape::Json.dump(message)
|
||||
else
|
||||
::MultiJson.dump(message)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def wrap_message(message)
|
||||
if active_model?(message)
|
||||
::ActiveModelSerializers::SerializableResource.new(
|
||||
message,
|
||||
serializer: ActiveModel::Serializer::ErrorSerializer
|
||||
).as_json
|
||||
elsif ok_to_pass_through?(message)
|
||||
message
|
||||
else
|
||||
{ error: message }
|
||||
end
|
||||
end
|
||||
|
||||
def active_model?(message)
|
||||
message.respond_to?(:errors) &&
|
||||
message.errors.is_a?(ActiveModel::Errors)
|
||||
end
|
||||
|
||||
def ok_to_pass_through?(message)
|
||||
message.is_a?(Exceptions::ValidationErrors) ||
|
||||
message.is_a?(Hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
module Grape
|
||||
module Formatter
|
||||
module ActiveModelSerializers
|
||||
class ActiveModelSerializers
|
||||
class << self
|
||||
def call(resource, env)
|
||||
options = build_options(resource, env)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module Grape
|
|||
end
|
||||
|
||||
def options
|
||||
@options ||= (
|
||||
@options ||= begin
|
||||
options = endpoint_options
|
||||
options[:scope] = endpoint unless options.key?(:scope)
|
||||
options.merge!(default_root_options) unless options.key?(:root)
|
||||
|
|
@ -15,7 +15,7 @@ module Grape
|
|||
options.merge!(adapter_options)
|
||||
options.merge!(extra_options)
|
||||
options
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -49,11 +49,7 @@ module Grape
|
|||
end
|
||||
|
||||
def innermost_scope
|
||||
if endpoint.respond_to?(:namespace_stackable)
|
||||
endpoint.namespace_stackable(:namespace).last
|
||||
else
|
||||
endpoint.settings.peek[:namespace]
|
||||
end
|
||||
endpoint.inheritable_setting.namespace_stackable[:namespace]&.last
|
||||
end
|
||||
|
||||
def meta_options
|
||||
|
|
@ -73,6 +69,7 @@ module Grape
|
|||
def extra_options
|
||||
options = env['ams_extra'] || {}
|
||||
return options if options.is_a?(Hash)
|
||||
|
||||
raise 'Extra options must be a hash'
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module Grape
|
|||
end
|
||||
|
||||
def serializer
|
||||
serializer_class.new(resource, serializer_options) if serializer_class
|
||||
serializer_class&.new(resource, serializer_options)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -16,12 +16,15 @@ module Grape
|
|||
|
||||
def serializer_class
|
||||
return @serializer_class if defined?(@serializer_class)
|
||||
@serializer_class = resource_defined_class
|
||||
@serializer_class ||= collection_class
|
||||
@serializer_class ||= options[:serializer]
|
||||
@serializer_class ||= namespace_inferred_class
|
||||
@serializer_class ||= version_inferred_class
|
||||
@serializer_class ||= resource_serializer_class
|
||||
|
||||
return nil if options.key?(:serializer) && options[:serializer].nil?
|
||||
|
||||
@serializer_class = resource_defined_class ||
|
||||
collection_class ||
|
||||
options[:serializer] ||
|
||||
namespace_inferred_class ||
|
||||
version_inferred_class ||
|
||||
resource_serializer_class
|
||||
end
|
||||
|
||||
def serializer_options
|
||||
|
|
@ -55,12 +58,14 @@ module Grape
|
|||
|
||||
def namespace_inferred_class
|
||||
return nil unless options.key?(:for)
|
||||
|
||||
namespace = options[:for].to_s.deconstantize
|
||||
"#{namespace}::#{resource_serializer_klass}".safe_constantize
|
||||
end
|
||||
|
||||
def version_inferred_class
|
||||
return nil unless options.key?(:version)
|
||||
|
||||
"#{version}::#{resource_serializer_klass}".safe_constantize
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
module Grape
|
||||
module ActiveModelSerializers
|
||||
VERSION = '1.5.1'.freeze
|
||||
VERSION = '2.0.2'.freeze
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ describe 'Grape::EndpointExtension' do
|
|||
subject do
|
||||
Grape::Endpoint.new(
|
||||
Grape::Util::InheritableSetting.new,
|
||||
path: '/',
|
||||
path: '/',
|
||||
method: 'foo'
|
||||
)
|
||||
end
|
||||
|
|
@ -27,7 +27,7 @@ describe 'Grape::EndpointExtension' do
|
|||
|
||||
describe '#render' do
|
||||
let(:env) { {} }
|
||||
let(:env_key) {}
|
||||
let(:env_key) { nil }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:env).and_return(env)
|
||||
|
|
|
|||
92
spec/grape-active_model_serializers/error_formatter_spec.rb
Normal file
92
spec/grape-active_model_serializers/error_formatter_spec.rb
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
require 'spec_helper'
|
||||
require 'grape-active_model_serializers/error_formatter'
|
||||
|
||||
describe Grape::ErrorFormatter::ActiveModelSerializers do
|
||||
subject { Grape::ErrorFormatter::ActiveModelSerializers }
|
||||
let(:backtrace) { ['Line:1'] }
|
||||
let(:options) { {} }
|
||||
let(:env) { { 'api.endpoint' => app.endpoints.first } }
|
||||
let(:original_exception) { StandardError.new('oh noes!') }
|
||||
|
||||
let(:app) {
|
||||
Class.new(Grape::API) do |app|
|
||||
app.format :json
|
||||
app.formatter :jsonapi, Grape::Formatter::ActiveModelSerializers
|
||||
app.error_formatter :jsonapi, Grape::ErrorFormatter::ActiveModelSerializers
|
||||
|
||||
app.namespace('space') do |ns|
|
||||
ns.get('/', root: false) do
|
||||
error!(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
let(:foo) {
|
||||
Class.new {
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :name
|
||||
|
||||
def initialize(attributes = {})
|
||||
super
|
||||
errors.add(:name, 'We don\'t like bears')
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
before do
|
||||
ActiveModel::Serializer.config.adapter = :json_api
|
||||
end
|
||||
|
||||
after do
|
||||
ActiveModel::Serializer.config.adapter = :json
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
context 'message is an activemodel' do
|
||||
let(:message) {
|
||||
foo.new(name: 'bar')
|
||||
}
|
||||
it 'formats the error' do
|
||||
result = subject
|
||||
.call(message, backtrace, options, env, original_exception)
|
||||
json_hash = JSON.parse(result)
|
||||
|
||||
expected_result = {
|
||||
'errors' => [
|
||||
{
|
||||
'source' => {
|
||||
'pointer' => '/data/attributes/name'
|
||||
},
|
||||
'detail' => 'We don\'t like bears'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
expect(json_hash == expected_result).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'message is hash like' do
|
||||
let(:message) { { 'errors' => ['error'] } }
|
||||
it 'passes the message through' do
|
||||
result = subject
|
||||
.call(message, backtrace, options, env, original_exception)
|
||||
json_hash = JSON.parse(result)
|
||||
|
||||
expect(json_hash == message).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'message is text' do
|
||||
let(:message) { 'error' }
|
||||
it 'wraps the error' do
|
||||
result = subject
|
||||
.call(message, backtrace, options, env, original_exception)
|
||||
json_hash = JSON.parse(result)
|
||||
|
||||
expect(json_hash == { 'error' => message }).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -18,8 +18,8 @@ describe Grape::Formatter::ActiveModelSerializers do
|
|||
{
|
||||
user: {
|
||||
first_name: 'JR',
|
||||
last_name: 'HE',
|
||||
email: 'jrhe@github.com'
|
||||
last_name: 'HE',
|
||||
email: 'jrhe@github.com'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'grape-active_model_serializers' do
|
||||
end
|
||||
|
|
@ -12,7 +12,7 @@ describe Grape::ActiveModelSerializers::OptionsBuilder do
|
|||
let(:env) { super().merge('ams_meta' => meta_options) }
|
||||
let(:meta_options) {
|
||||
{
|
||||
meta: meta,
|
||||
meta: meta,
|
||||
meta_key: meta_key
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ describe Grape::ActiveModelSerializers::SerializerResolver do
|
|||
let(:options) {
|
||||
{
|
||||
serializer: options_serializer_class, # options defined
|
||||
for: V4::UsersApi, # namespace inference
|
||||
version: 'v5' # version inference
|
||||
for: V4::UsersApi, # namespace inference
|
||||
version: 'v5' # version inference
|
||||
}
|
||||
}
|
||||
# resource defined
|
||||
|
|
@ -52,6 +52,18 @@ describe Grape::ActiveModelSerializers::SerializerResolver do
|
|||
expect(serializer).to be_kind_of(serializer_class)
|
||||
end
|
||||
|
||||
context 'specified nil by options' do
|
||||
let(:options) {
|
||||
super().merge(
|
||||
serializer: nil
|
||||
)
|
||||
}
|
||||
|
||||
it 'returns nil' do
|
||||
expect(serializer).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'each serializer' do
|
||||
let(:options) {
|
||||
super().except(:serializer).merge(
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ describe 'Sequel Integration' do
|
|||
let!(:model) {
|
||||
SequelUser = Class.new(Sequel::Model(:users)) do
|
||||
include ActiveModel::Serialization
|
||||
|
||||
def self.model_name
|
||||
'User'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ describe Grape::ActiveModelSerializers do
|
|||
app.get('/home') do
|
||||
User.new(
|
||||
first_name: 'JR',
|
||||
last_name: 'HE',
|
||||
email: 'contact@jrhe.co.uk'
|
||||
last_name: 'HE',
|
||||
email: 'contact@jrhe.co.uk'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -60,17 +60,17 @@ describe Grape::ActiveModelSerializers do
|
|||
app.get('/users') do
|
||||
user = User.new(
|
||||
first_name: 'JR',
|
||||
last_name: 'HE',
|
||||
email: 'contact@jrhe.co.uk'
|
||||
last_name: 'HE',
|
||||
email: 'contact@jrhe.co.uk'
|
||||
)
|
||||
[user, user]
|
||||
end
|
||||
|
||||
get '/users'
|
||||
expect(subject).to eq(
|
||||
'{"users":['\
|
||||
'{"first_name":"JR","last_name":"HE"},'\
|
||||
'{"first_name":"JR","last_name":"HE"}'\
|
||||
'{"users":[' \
|
||||
'{"first_name":"JR","last_name":"HE"},' \
|
||||
'{"first_name":"JR","last_name":"HE"}' \
|
||||
']}'
|
||||
)
|
||||
end
|
||||
|
|
@ -83,8 +83,8 @@ describe Grape::ActiveModelSerializers do
|
|||
|
||||
get '/home'
|
||||
expect(subject).to eq(
|
||||
'{"blog_post":'\
|
||||
'{"title":"Grape AM::S Rocks!","body":"Really, it does."}'\
|
||||
'{"blog_post":' \
|
||||
'{"title":"Grape AM::S Rocks!","body":"Really, it does."}' \
|
||||
'}'
|
||||
)
|
||||
end
|
||||
|
|
@ -93,16 +93,16 @@ describe Grape::ActiveModelSerializers do
|
|||
app.get('/blog_posts') do
|
||||
blog_post = BlogPost.new(
|
||||
title: 'Grape AM::S Rocks!',
|
||||
body: 'Really, it does.'
|
||||
body: 'Really, it does.'
|
||||
)
|
||||
[blog_post, blog_post]
|
||||
end
|
||||
|
||||
get '/blog_posts'
|
||||
expect(subject).to eq(
|
||||
'{"blog_posts":['\
|
||||
'{"title":"Grape AM::S Rocks!","body":"Really, it does."},'\
|
||||
'{"title":"Grape AM::S Rocks!","body":"Really, it does."}'\
|
||||
'{"blog_posts":[' \
|
||||
'{"title":"Grape AM::S Rocks!","body":"Really, it does."},' \
|
||||
'{"title":"Grape AM::S Rocks!","body":"Really, it does."}' \
|
||||
']}'
|
||||
)
|
||||
end
|
||||
|
|
@ -132,9 +132,9 @@ describe Grape::ActiveModelSerializers do
|
|||
|
||||
get '/admin/jeff'
|
||||
expect(subject).to eq(
|
||||
'{"admin":['\
|
||||
'{"first_name":"Jeff","last_name":null},'\
|
||||
'{"first_name":"Jeff","last_name":null}'\
|
||||
'{"admin":[' \
|
||||
'{"first_name":"Jeff","last_name":null},' \
|
||||
'{"first_name":"Jeff","last_name":null}' \
|
||||
']}'
|
||||
)
|
||||
end
|
||||
|
|
@ -149,9 +149,9 @@ describe Grape::ActiveModelSerializers do
|
|||
|
||||
get '/people'
|
||||
expect(subject).to eq(
|
||||
'{"people":['\
|
||||
'{"first_name":"Jeff","last_name":null},'\
|
||||
'{"first_name":"Jeff","last_name":null}'\
|
||||
'{"people":[' \
|
||||
'{"first_name":"Jeff","last_name":null},' \
|
||||
'{"first_name":"Jeff","last_name":null}' \
|
||||
']}'
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@ RSpec.configure do |config|
|
|||
config.include Rack::Test::Methods
|
||||
end
|
||||
|
||||
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
||||
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }
|
||||
|
|
|
|||
Loading…
Reference in a new issue