diff --git a/lib/fast_jsonapi/object_serializer.rb b/lib/fast_jsonapi/object_serializer.rb index 76caa7d..355c8ba 100644 --- a/lib/fast_jsonapi/object_serializer.rb +++ b/lib/fast_jsonapi/object_serializer.rb @@ -167,8 +167,8 @@ module FastJsonapi self.record_type = run_key_transform(type_name) end - def set_id(id_name) - self.record_id = id_name + def set_id(id_name = nil, &block) + self.record_id = block || id_name end def cache_options(cache_options) diff --git a/lib/fast_jsonapi/serialization_core.rb b/lib/fast_jsonapi/serialization_core.rb index a456b21..200af9b 100644 --- a/lib/fast_jsonapi/serialization_core.rb +++ b/lib/fast_jsonapi/serialization_core.rb @@ -86,9 +86,10 @@ module FastJsonapi end def id_from_record(record) - return record.send(record_id) if record_id - raise MandatoryField, 'id is a mandatory field in the jsonapi spec' unless record.respond_to?(:id) - record.id + return record_id.call(record) if record_id.is_a?(Proc) + return record.send(record_id) if record_id + raise MandatoryField, 'id is a mandatory field in the jsonapi spec' unless record.respond_to?(:id) + record.id end # Override #to_json for alternative implementation diff --git a/spec/lib/object_serializer_class_methods_spec.rb b/spec/lib/object_serializer_class_methods_spec.rb index 347b188..2c2ed6b 100644 --- a/spec/lib/object_serializer_class_methods_spec.rb +++ b/spec/lib/object_serializer_class_methods_spec.rb @@ -195,28 +195,57 @@ describe FastJsonapi::ObjectSerializer do describe '#set_id' do subject(:serializable_hash) { MovieSerializer.new(resource).serializable_hash } - before do - MovieSerializer.set_id :owner_id - end + context 'method name' do + before do + MovieSerializer.set_id :owner_id + end - after do - MovieSerializer.set_id nil - end + after do + MovieSerializer.set_id nil + end - context 'when one record is given' do - let(:resource) { movie } + context 'when one record is given' do + let(:resource) { movie } - it 'returns correct hash which id equals owner_id' do - expect(serializable_hash[:data][:id].to_i).to eq movie.owner_id + it 'returns correct hash which id equals owner_id' do + expect(serializable_hash[:data][:id].to_i).to eq movie.owner_id + end + end + + context 'when an array of records is given' do + let(:resource) { [movie, movie] } + + it 'returns correct hash which id equals owner_id' do + expect(serializable_hash[:data][0][:id].to_i).to eq movie.owner_id + expect(serializable_hash[:data][1][:id].to_i).to eq movie.owner_id + end end end - context 'when an array of records is given' do - let(:resource) { [movie, movie] } + context 'with block' do + before do + MovieSerializer.set_id { |record| "movie-#{record.owner_id}" } + end - it 'returns correct hash which id equals owner_id' do - expect(serializable_hash[:data][0][:id].to_i).to eq movie.owner_id - expect(serializable_hash[:data][1][:id].to_i).to eq movie.owner_id + after do + MovieSerializer.set_id nil + end + + context 'when one record is given' do + let(:resource) { movie } + + it 'returns correct hash which id equals movie-id' do + expect(serializable_hash[:data][:id]).to eq "movie-#{movie.owner_id}" + end + end + + context 'when an array of records is given' do + let(:resource) { [movie, movie] } + + it 'returns correct hash which id equals movie-id' do + expect(serializable_hash[:data][0][:id]).to eq "movie-#{movie.owner_id}" + expect(serializable_hash[:data][1][:id]).to eq "movie-#{movie.owner_id}" + end end end end