Skip to content

Commit bad004f

Browse files
TrevorHinesleyshishirmk
authored andcommitted
Allow conditional attributes
1 parent 44d5e0f commit bad004f

4 files changed

Lines changed: 64 additions & 2 deletions

File tree

lib/fast_jsonapi/object_serializer.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,18 @@ def cache_options(cache_options)
149149

150150
def attributes(*attributes_list, &block)
151151
attributes_list = attributes_list.first if attributes_list.first.class.is_a?(Array)
152+
options = attributes_list.last.is_a?(Hash) ? attributes_list.pop : {}
152153
self.attributes_to_serialize = {} if self.attributes_to_serialize.nil?
154+
self.optional_attributes_to_serialize = {} if self.optional_attributes_to_serialize.nil?
155+
153156
attributes_list.each do |attr_name|
154157
method_name = attr_name
155158
key = run_key_transform(method_name)
156-
attributes_to_serialize[key] = block || method_name
159+
if options[:if].present?
160+
optional_attributes_to_serialize[key] = [method_name, options[:if]]
161+
else
162+
attributes_to_serialize[key] = block || method_name
163+
end
157164
end
158165
end
159166

lib/fast_jsonapi/serialization_core.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module SerializationCore
1212
included do
1313
class << self
1414
attr_accessor :attributes_to_serialize,
15+
:optional_attributes_to_serialize,
1516
:relationships_to_serialize,
1617
:cachable_relationships_to_serialize,
1718
:uncachable_relationships_to_serialize,
@@ -73,13 +74,21 @@ def links_hash(record, params = {})
7374
end
7475

7576
def attributes_hash(record, params = {})
76-
attributes_to_serialize.each_with_object({}) do |(key, method), attr_hash|
77+
attributes = attributes_to_serialize.each_with_object({}) do |(key, method), attr_hash|
7778
attr_hash[key] = if method.is_a?(Proc)
7879
method.arity == 1 ? method.call(record) : method.call(record, params)
7980
else
8081
record.public_send(method)
8182
end
8283
end
84+
85+
self.optional_attributes_to_serialize = {} if self.optional_attributes_to_serialize.nil?
86+
optional_attributes_to_serialize.each do |key, details|
87+
method_name, check_proc = details
88+
attributes[key] = record.send(method_name) if check_proc.call(record, params)
89+
end
90+
91+
attributes
8392
end
8493

8594
def relationships_hash(record, relationships = nil, params = {})

spec/lib/object_serializer_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,4 +309,36 @@ class BlahSerializer
309309
expect(serializable_hash[:included][0][:links][:self]).to eq url
310310
end
311311
end
312+
313+
context 'when optional attributes are determined by record data' do
314+
it 'returns optional attribute when attribute is included' do
315+
movie.release_year = 2001
316+
json = MovieOptionalRecordDataSerializer.new(movie).serialized_json
317+
serializable_hash = JSON.parse(json)
318+
expect(serializable_hash['data']['attributes']['release_year']).to eq movie.release_year
319+
end
320+
321+
it "doesn't return optional attribute when attribute is not included" do
322+
movie.release_year = 1970
323+
json = MovieOptionalRecordDataSerializer.new(movie).serialized_json
324+
serializable_hash = JSON.parse(json)
325+
expect(serializable_hash['data']['attributes'].has_key?('release_year')).to be_falsey
326+
end
327+
end
328+
329+
context 'when optional attributes are determined by params data' do
330+
it 'returns optional attribute when attribute is included' do
331+
movie.director = 'steven spielberg'
332+
json = MovieOptionalParamsDataSerializer.new(movie, { params: { admin: true }}).serialized_json
333+
serializable_hash = JSON.parse(json)
334+
expect(serializable_hash['data']['attributes']['director']).to eq 'steven spielberg'
335+
end
336+
337+
it "doesn't return optional attribute when attribute is not included" do
338+
movie.director = 'steven spielberg'
339+
json = MovieOptionalParamsDataSerializer.new(movie, { params: { admin: false }}).serialized_json
340+
serializable_hash = JSON.parse(json)
341+
expect(serializable_hash['data']['attributes'].has_key?('director')).to be_falsey
342+
end
343+
end
312344
end

spec/shared/contexts/movie_context.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,20 @@ class AccountSerializer
278278
set_type :account
279279
belongs_to :supplier
280280
end
281+
282+
class MovieOptionalRecordDataSerializer
283+
include FastJsonapi::ObjectSerializer
284+
set_type :movie
285+
attributes :name
286+
attribute :release_year, if: Proc.new { |record| record.release_year >= 2000 }
287+
end
288+
289+
class MovieOptionalParamsDataSerializer
290+
include FastJsonapi::ObjectSerializer
291+
set_type :movie
292+
attributes :name
293+
attribute :director, if: Proc.new { |record, params| params && params[:admin] == true }
294+
end
281295
end
282296

283297

0 commit comments

Comments
 (0)