Allow conditional attributes
This commit is contained in:
parent
44d5e0f9c5
commit
bad004fd42
@ -149,11 +149,18 @@ module FastJsonapi
|
|||||||
|
|
||||||
def attributes(*attributes_list, &block)
|
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)
|
||||||
|
options = attributes_list.last.is_a?(Hash) ? attributes_list.pop : {}
|
||||||
self.attributes_to_serialize = {} if self.attributes_to_serialize.nil?
|
self.attributes_to_serialize = {} if self.attributes_to_serialize.nil?
|
||||||
|
self.optional_attributes_to_serialize = {} if self.optional_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] = block || method_name
|
if options[:if].present?
|
||||||
|
optional_attributes_to_serialize[key] = [method_name, options[:if]]
|
||||||
|
else
|
||||||
|
attributes_to_serialize[key] = block || method_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ module FastJsonapi
|
|||||||
included do
|
included do
|
||||||
class << self
|
class << self
|
||||||
attr_accessor :attributes_to_serialize,
|
attr_accessor :attributes_to_serialize,
|
||||||
|
:optional_attributes_to_serialize,
|
||||||
:relationships_to_serialize,
|
:relationships_to_serialize,
|
||||||
:cachable_relationships_to_serialize,
|
:cachable_relationships_to_serialize,
|
||||||
:uncachable_relationships_to_serialize,
|
:uncachable_relationships_to_serialize,
|
||||||
@ -73,13 +74,21 @@ module FastJsonapi
|
|||||||
end
|
end
|
||||||
|
|
||||||
def attributes_hash(record, params = {})
|
def attributes_hash(record, params = {})
|
||||||
attributes_to_serialize.each_with_object({}) do |(key, method), attr_hash|
|
attributes = attributes_to_serialize.each_with_object({}) do |(key, method), attr_hash|
|
||||||
attr_hash[key] = if method.is_a?(Proc)
|
attr_hash[key] = if method.is_a?(Proc)
|
||||||
method.arity == 1 ? method.call(record) : method.call(record, params)
|
method.arity == 1 ? method.call(record) : method.call(record, params)
|
||||||
else
|
else
|
||||||
record.public_send(method)
|
record.public_send(method)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.optional_attributes_to_serialize = {} if self.optional_attributes_to_serialize.nil?
|
||||||
|
optional_attributes_to_serialize.each do |key, details|
|
||||||
|
method_name, check_proc = details
|
||||||
|
attributes[key] = record.send(method_name) if check_proc.call(record, params)
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes
|
||||||
end
|
end
|
||||||
|
|
||||||
def relationships_hash(record, relationships = nil, params = {})
|
def relationships_hash(record, relationships = nil, params = {})
|
||||||
|
|||||||
@ -309,4 +309,36 @@ describe FastJsonapi::ObjectSerializer do
|
|||||||
expect(serializable_hash[:included][0][:links][:self]).to eq url
|
expect(serializable_hash[:included][0][:links][:self]).to eq url
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when optional attributes are determined by record data' do
|
||||||
|
it 'returns optional attribute when attribute is included' do
|
||||||
|
movie.release_year = 2001
|
||||||
|
json = MovieOptionalRecordDataSerializer.new(movie).serialized_json
|
||||||
|
serializable_hash = JSON.parse(json)
|
||||||
|
expect(serializable_hash['data']['attributes']['release_year']).to eq movie.release_year
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't return optional attribute when attribute is not included" do
|
||||||
|
movie.release_year = 1970
|
||||||
|
json = MovieOptionalRecordDataSerializer.new(movie).serialized_json
|
||||||
|
serializable_hash = JSON.parse(json)
|
||||||
|
expect(serializable_hash['data']['attributes'].has_key?('release_year')).to be_falsey
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when optional attributes are determined by params data' do
|
||||||
|
it 'returns optional attribute when attribute is included' do
|
||||||
|
movie.director = 'steven spielberg'
|
||||||
|
json = MovieOptionalParamsDataSerializer.new(movie, { params: { admin: true }}).serialized_json
|
||||||
|
serializable_hash = JSON.parse(json)
|
||||||
|
expect(serializable_hash['data']['attributes']['director']).to eq 'steven spielberg'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't return optional attribute when attribute is not included" do
|
||||||
|
movie.director = 'steven spielberg'
|
||||||
|
json = MovieOptionalParamsDataSerializer.new(movie, { params: { admin: false }}).serialized_json
|
||||||
|
serializable_hash = JSON.parse(json)
|
||||||
|
expect(serializable_hash['data']['attributes'].has_key?('director')).to be_falsey
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -278,6 +278,20 @@ RSpec.shared_context 'movie class' do
|
|||||||
set_type :account
|
set_type :account
|
||||||
belongs_to :supplier
|
belongs_to :supplier
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class MovieOptionalRecordDataSerializer
|
||||||
|
include FastJsonapi::ObjectSerializer
|
||||||
|
set_type :movie
|
||||||
|
attributes :name
|
||||||
|
attribute :release_year, if: Proc.new { |record| record.release_year >= 2000 }
|
||||||
|
end
|
||||||
|
|
||||||
|
class MovieOptionalParamsDataSerializer
|
||||||
|
include FastJsonapi::ObjectSerializer
|
||||||
|
set_type :movie
|
||||||
|
attributes :name
|
||||||
|
attribute :director, if: Proc.new { |record, params| params && params[:admin] == true }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user