Skip to content

Commit

Permalink
Merge pull request #3 from jsonapi-serializer/master
Browse files Browse the repository at this point in the history
Pull in updates from upstream
  • Loading branch information
tatthurs authored Jun 14, 2024
2 parents c337603 + 55df2b7 commit abd5960
Show file tree
Hide file tree
Showing 19 changed files with 123 additions and 33 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
21 changes: 17 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,36 @@ on: [push, pull_request]

jobs:
tests:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby: [2.4, 2.5, 2.6, 2.7]
ruby: [2.4, 2.7, '3.0', 3.1, 3.2, truffleruby-head]

steps:
- uses: actions/checkout@master
- uses: actions/checkout@v3

- name: Sets up the Ruby version
uses: actions/setup-ruby@v1
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}

- name: Sets up the environment
run: |
sudo apt-get install libsqlite3-dev
- name: Install legacy bundler for Ruby 2.4
if: ${{ matrix.ruby == 2.4 }}
run: |
gem install -q bundler -v 2.3.26
- name: Install bundler 2.4+ for modern Rubies
if: ${{ matrix.ruby != 2.4 }}
run: |
gem install -q bundler
- name: Run bundle install
run: |
bundle install
- name: Runs code QA and tests
Expand Down
24 changes: 24 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ require:
- rubocop-performance
- rubocop-rspec

AllCops:
NewCops: enable
SuggestExtensions: false

Style/FrozenStringLiteralComment:
Enabled: false

Expand Down Expand Up @@ -38,6 +42,9 @@ Performance/TimesMap:
Exclude:
- 'spec/**/**.rb'

Gemspec/RequiredRubyVersion:
Enabled: false

# TODO: Fix these...
Style/Documentation:
Enabled: false
Expand Down Expand Up @@ -76,3 +83,20 @@ Naming/PredicateName:
Naming/AccessorMethodName:
Exclude:
- 'lib/**/**.rb'

Style/CaseLikeIf:
Exclude:
- 'lib/fast_jsonapi/object_serializer.rb'

Style/OptionalBooleanParameter:
Exclude:
- 'lib/fast_jsonapi/serialization_core.rb'
- 'lib/fast_jsonapi/relationship.rb'

Lint/DuplicateBranch:
Exclude:
- 'lib/fast_jsonapi/relationship.rb'

Style/DocumentDynamicEvalDefinition:
Exclude:
- 'lib/extensions/has_one.rb'
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
- ...

## [2.2.0] - 2021-03-11

### Added
- Proper error is raised on unsupported includes (#125)

### Changed
- Documentation updates (#137 #139 #143 #146)

### Fixed
- Empty relationships are no longer added to serialized doc (#116)
- Ruby v3 compatibility (#160)

## [2.1.0] - 2020-08-30

### Added
Expand Down
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# JSON:API Serialization Library

## :warning: :construction: [At the moment, contributions are welcome only for v3](https://github.com/jsonapi-serializer/jsonapi-serializer/pull/141)! :construction: :warning:
## :warning: :construction: v2 (the `master` branch) is in maintenance mode! :construction: :warning:

We'll gladly accept bugfixes and security-related fixes for v2 (the `master` branch), but at this stage, contributions for new features/improvements are welcome only for v3. Please feel free to leave comments in the [v3 Pull Request](https://github.com/jsonapi-serializer/jsonapi-serializer/pull/141).

---

A fast [JSON:API](https://jsonapi.org/) serializer for Ruby Objects.

Expand Down Expand Up @@ -38,6 +42,7 @@ article in the `docs` folder for any questions related to methodology.
* [Conditional Attributes](#conditional-attributes)
* [Conditional Relationships](#conditional-relationships)
* [Specifying a Relationship Serializer](#specifying-a-relationship-serializer)
* [Ordering `has_many` Relationship](#ordering-has_many-relationship)
* [Sparse Fieldsets](#sparse-fieldsets)
* [Using helper methods](#using-helper-methods)
* [Performance Instrumentation](#performance-instrumentation)
Expand Down Expand Up @@ -405,7 +410,7 @@ end
`#fetch(record, **options, &block)` method:

- `record` is the record that is currently serialized
- `options` is everything that was passed to `cache_options` except `store`, so it can be everyhing the cache store supports
- `options` is everything that was passed to `cache_options` except `store`, so it can be everything the cache store supports
- `&block` should be executed to fetch new data if cache is empty

So for the example above it will call the cache instance like this:
Expand Down Expand Up @@ -462,7 +467,7 @@ class MovieSerializer

belongs_to :primary_agent do |movie, params|
# in here, params is a hash containing the `:current_user` key
params[:current_user].is_employee? ? true : false
params[:current_user]
end
end

Expand Down Expand Up @@ -575,6 +580,20 @@ class MovieSerializer
end
```

### Ordering `has_many` Relationship

You can order the `has_many` relationship by providing a block:

```ruby
class MovieSerializer
include JSONAPI::Serializer

has_many :actors do |movie|
movie.actors.order(position: :asc)
end
end
```

### Sparse Fieldsets

Attributes and relationships can be selectively returned per record type by using the `fields` option.
Expand Down
5 changes: 3 additions & 2 deletions jsonapi-serializer.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Gem::Specification.new do |gem|
gem.email = ''

gem.summary = 'Fast JSON:API serialization library'
gem.description = 'Fast, simple and easy to use '\
'JSON:API serialization library (also known as fast_jsonapi).'
gem.description = 'Fast, simple and easy to use ' \
'JSON:API serialization library (also known as fast_jsonapi).'
gem.homepage = 'https://github.com/jsonapi-serializer/jsonapi-serializer'
gem.licenses = ['Apache-2.0']
gem.files = Dir['lib/**/*']
Expand All @@ -33,4 +33,5 @@ Gem::Specification.new do |gem|
gem.add_development_dependency('rubocop-rspec')
gem.add_development_dependency('simplecov')
gem.add_development_dependency('sqlite3')
gem.metadata['rubygems_mfa_required'] = 'true'
end
2 changes: 1 addition & 1 deletion lib/extensions/has_one.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

::ActiveRecord::Associations::Builder::HasOne.class_eval do
ActiveRecord::Associations::Builder::HasOne.class_eval do
# Based on
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/associations/builder/collection_association.rb#L50
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/associations/builder/singular_association.rb#L11
Expand Down
11 changes: 10 additions & 1 deletion lib/fast_jsonapi/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ class << self
# @param [Array<Object>] *params any number of parameters to be passed to the Proc
# @return [Object] the result of the Proc call with the supplied parameters
def call_proc(proc, *params)
proc.call(*params.take(proc.parameters.length))
# The parameters array for a lambda created from a symbol (&:foo) differs
# from explictly defined procs/lambdas, so we can't deduce the number of
# parameters from the array length (and differs between Ruby 2.x and 3).
# In the case of negative arity -- unlimited/unknown argument count --
# just send the object to act as the method receiver.
if proc.arity.negative?
proc.call(params.first)
else
proc.call(*params.take(proc.parameters.length))
end
end
end
end
15 changes: 7 additions & 8 deletions lib/fast_jsonapi/object_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require 'active_support'
require 'active_support/time'
require 'active_support/concern'
require 'active_support/inflector'
Expand Down Expand Up @@ -133,9 +134,7 @@ def inherited(subclass)
def reflected_record_type
return @reflected_record_type if defined?(@reflected_record_type)

@reflected_record_type ||= begin
name.split('::').last.chomp('Serializer').underscore.to_sym if name&.end_with?('Serializer')
end
@reflected_record_type ||= (name.split('::').last.chomp('Serializer').underscore.to_sym if name&.end_with?('Serializer'))
end

def set_key_transform(transform_name)
Expand Down Expand Up @@ -228,10 +227,10 @@ def add_relationship(relationship)

# TODO: Remove this undocumented option.
# Delegate the caching to the serializer exclusively.
if !relationship.cached
uncachable_relationships_to_serialize[relationship.name] = relationship
else
if relationship.cached
cachable_relationships_to_serialize[relationship.name] = relationship
else
uncachable_relationships_to_serialize[relationship.name] = relationship
end
relationships_to_serialize[relationship.name] = relationship
end
Expand Down Expand Up @@ -302,7 +301,7 @@ def compute_id_method_name(custom_id_method_name, id_method_name_from_relationsh

def serializer_for(name)
namespace = self.name.gsub(/()?\w+Serializer$/, '')
serializer_name = name.to_s.demodulize.classify + 'Serializer'
serializer_name = "#{name.to_s.demodulize.classify}Serializer"
serializer_class_name = namespace + serializer_name
begin
serializer_class_name.constantize
Expand Down Expand Up @@ -340,7 +339,7 @@ def link(*params, &block)
def validate_includes!(includes)
return if includes.blank?

parse_includes_list(includes).keys.each do |include_item|
parse_includes_list(includes).each_key do |include_item|
relationship_to_include = relationships_to_serialize[include_item]
raise(JSONAPI::Serializer::UnsupportedIncludeError.new(include_item, name)) unless relationship_to_include

Expand Down
2 changes: 1 addition & 1 deletion lib/fast_jsonapi/relationship.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ def initialize(
object_block:,
serializer:,
relationship_type:,
cached: false,
polymorphic:,
conditional_proc:,
transform_method:,
links:,
meta:,
cached: false,
lazy_load_data: false
)
@owner = owner
Expand Down
1 change: 1 addition & 0 deletions lib/fast_jsonapi/serialization_core.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require 'active_support'
require 'active_support/concern'
require 'digest/sha1'

Expand Down
2 changes: 2 additions & 0 deletions lib/jsonapi/serializer/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
module JSONAPI
module Serializer
class Error < StandardError; end

class UnsupportedIncludeError < Error
attr_reader :include_item, :klass

def initialize(include_item, klass)
super()
@include_item = include_item
@klass = klass
end
Expand Down
1 change: 1 addition & 0 deletions lib/jsonapi/serializer/instrumentation.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'active_support'
require 'active_support/notifications'

module JSONAPI
Expand Down
2 changes: 1 addition & 1 deletion lib/jsonapi/serializer/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module JSONAPI
module Serializer
VERSION = '2.1.0'.freeze
VERSION = '2.2.0'.freeze
end
end
1 change: 1 addition & 0 deletions spec/fixtures/_user.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'active_support'
require 'active_support/cache'

class User
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/actor.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'active_support'
require 'active_support/cache'
require 'jsonapi/serializer/instrumentation'

Expand Down
5 changes: 3 additions & 2 deletions spec/fixtures/movie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def url(obj = nil)
@url ||= FFaker::Internet.http_url
return @url if obj.nil?

@url + '?' + obj.hash.to_s
"#{@url}?#{obj.hash}"
end

def owner=(ownr)
Expand All @@ -48,8 +48,9 @@ class MovieSerializer

set_type :movie

attribute :released_in_year, &:year
attributes :name
attribute :release_year do |object|
attribute :release_year do |object, _params|
object.year
end

Expand Down
6 changes: 2 additions & 4 deletions spec/integration/instrumentation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@

it do
payload = event_name = nil
notification_name = (
::JSONAPI::Serializer::Instrumentation::NOTIFICATION_NAMESPACE +
'serializable_hash'
)
notification_name =
"#{JSONAPI::Serializer::Instrumentation::NOTIFICATION_NAMESPACE}serializable_hash"

ActiveSupport::Notifications.subscribe(
notification_name
Expand Down
14 changes: 8 additions & 6 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
require 'simplecov'

SimpleCov.start do
add_group 'Lib', 'lib'
add_group 'Tests', 'spec'
unless RUBY_ENGINE == 'truffleruby'
require 'simplecov'
SimpleCov.start do
add_group 'Lib', 'lib'
add_group 'Tests', 'spec'
end
SimpleCov.minimum_coverage 90
end
SimpleCov.minimum_coverage 90

require 'active_support'
require 'active_support/core_ext/object/json'
require 'jsonapi/serializer'
require 'ffaker'
Expand Down

0 comments on commit abd5960

Please sign in to comment.