ability to customize rendering of attributes via a block (#54)
* add hash benchmarking to performance tests * Add missing attribute in README example * Disable GC before doing performance test * Enable oj to AM for fair benchmark test * ability to customize rendering of attributes via a block * fixed attribute render spec * minimized specs to specifially test this feature * Update README to include attribute definitions * Fixed syntax error * Fixed merge issues
This commit is contained in:
parent
6d516c217c
commit
b30a53bc5f
39
README.md
39
README.md
@ -155,6 +155,45 @@ set_key_transform :dash # "some_key" => "some-key"
|
|||||||
set_key_transform :underscore # "some_key" => "some_key"
|
set_key_transform :underscore # "some_key" => "some_key"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Attributes
|
||||||
|
Attributes are defined in FastJsonapi using the `attributes` method. This method is also aliased as `attribute`, which is useful when defining a single attribute.
|
||||||
|
|
||||||
|
By default, attributes are read directly from the model property of the same name. In this example, `name` is expected to be a property of the object being serialized:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class MovieSerializer
|
||||||
|
include FastJsonapi::ObjectSerializer
|
||||||
|
|
||||||
|
attribute :name
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Custom attributes that must be serialized but do not exist on the model can be declared using Ruby block syntax:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class MovieSerializer
|
||||||
|
include FastJsonapi::ObjectSerializer
|
||||||
|
|
||||||
|
attributes :name, :year
|
||||||
|
|
||||||
|
attribute :name_with_year do |object|
|
||||||
|
"#{object.name} (#{object.year})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
The block syntax can also be used to override the property on the object:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class MovieSerializer
|
||||||
|
include FastJsonapi::ObjectSerializer
|
||||||
|
|
||||||
|
attribute :name do |object|
|
||||||
|
"#{object.name} Part 2"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
### Compound Document
|
### Compound Document
|
||||||
|
|
||||||
Support for top-level included member through ` options[:include] `.
|
Support for top-level included member through ` options[:include] `.
|
||||||
|
@ -140,16 +140,18 @@ module FastJsonapi
|
|||||||
self.cache_length = cache_options[:cache_length] || 5.minutes
|
self.cache_length = cache_options[:cache_length] || 5.minutes
|
||||||
end
|
end
|
||||||
|
|
||||||
def attributes(*attributes_list)
|
def attributes(*attributes_list, &block)
|
||||||
attributes_list = attributes_list.first if attributes_list.first.class.is_a?(Array)
|
attributes_list = attributes_list.first if attributes_list.first.class.is_a?(Array)
|
||||||
self.attributes_to_serialize = {} if self.attributes_to_serialize.nil?
|
self.attributes_to_serialize = {} if self.attributes_to_serialize.nil?
|
||||||
attributes_list.each do |attr_name|
|
attributes_list.each do |attr_name|
|
||||||
method_name = attr_name
|
method_name = attr_name
|
||||||
key = run_key_transform(method_name)
|
key = run_key_transform(method_name)
|
||||||
attributes_to_serialize[key] = method_name
|
attributes_to_serialize[key] = block || method_name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
alias_method :attribute, :attributes
|
||||||
|
|
||||||
def add_relationship(name, relationship)
|
def add_relationship(name, relationship)
|
||||||
self.relationships_to_serialize = {} if relationships_to_serialize.nil?
|
self.relationships_to_serialize = {} if relationships_to_serialize.nil?
|
||||||
self.cachable_relationships_to_serialize = {} if cachable_relationships_to_serialize.nil?
|
self.cachable_relationships_to_serialize = {} if cachable_relationships_to_serialize.nil?
|
||||||
|
@ -52,8 +52,8 @@ module FastJsonapi
|
|||||||
end
|
end
|
||||||
|
|
||||||
def attributes_hash(record)
|
def attributes_hash(record)
|
||||||
attributes_to_serialize.each_with_object({}) do |(key, method_name), attr_hash|
|
attributes_to_serialize.each_with_object({}) do |(key, method), attr_hash|
|
||||||
attr_hash[key] = record.public_send(method_name)
|
attr_hash[key] = method.is_a?(Proc) ? method.call(record) : record.public_send(method)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
13
spec/lib/object_serializer_with_attribute_block_spec.rb
Normal file
13
spec/lib/object_serializer_with_attribute_block_spec.rb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe FastJsonapi::ObjectSerializer do
|
||||||
|
include_context 'movie class'
|
||||||
|
|
||||||
|
context 'when including attribute blocks' do
|
||||||
|
it 'returns correct hash when serializable_hash is called' do
|
||||||
|
serializable_hash = MovieSerializerWithAttributeBlock.new([movie]).serializable_hash
|
||||||
|
expect(serializable_hash[:data][0][:attributes][:name]).to eq movie.name
|
||||||
|
expect(serializable_hash[:data][0][:attributes][:title_with_year]).to eq "#{movie.name} (#{movie.release_year})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -96,6 +96,15 @@ RSpec.shared_context 'movie class' do
|
|||||||
attributes :name
|
attributes :name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class MovieSerializerWithAttributeBlock
|
||||||
|
include FastJsonapi::ObjectSerializer
|
||||||
|
set_type :movie
|
||||||
|
attributes :name, :release_year
|
||||||
|
attribute :title_with_year do |record|
|
||||||
|
"#{record.name} (#{record.release_year})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class SupplierSerializer
|
class SupplierSerializer
|
||||||
include FastJsonapi::ObjectSerializer
|
include FastJsonapi::ObjectSerializer
|
||||||
set_type :supplier
|
set_type :supplier
|
||||||
@ -140,6 +149,7 @@ RSpec.shared_context 'movie class' do
|
|||||||
ActorSerializer
|
ActorSerializer
|
||||||
MovieType
|
MovieType
|
||||||
MovieTypeSerializer
|
MovieTypeSerializer
|
||||||
|
MovieSerializerWithAttributeBlock
|
||||||
AppName::V1::MovieSerializer
|
AppName::V1::MovieSerializer
|
||||||
MovieStruct
|
MovieStruct
|
||||||
ActorStruct
|
ActorStruct
|
||||||
|
Loading…
x
Reference in New Issue
Block a user