Allow block for id customization
Allow an ID of object to be customized directly on the serializer by passing a block to `set_id` as opposed to only through a model property. We already allow for attributes that do not have a model property of the same name to be customized directly on the serializer using a block. This customization can be useful in situation in which you have different classes being serialized using the same serializer. For example, if we have `HorrorMovie`, `ComedyMovie` and `DramaMovie` using the same `MovieSerializer`, we can unify their IDs using ``` class MovieSerializer include FastJsonapi::ObjectSerializer attributes :name, :year set_id do |record| "#{record.name.downcase}-#{record.id}" end ``` which is preferable to creating a `#serialized_id` method in every model that will use `MovieSerializer` to encapsulate the customization. Closes #315
This commit is contained in:
parent
11b5255010
commit
9fa26fa588
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user