Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions lib/grape/jsonapi/entity/resource_identifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,28 @@ class << self
attr_reader :type_plural
end

def self.inherited(subclass)
class << subclass
attr_accessor :custom_id_proc
end
super(subclass)
end

def self.root(plural, singular = nil, for_real = false)
@type_plural = plural
super(plural, singular) if for_real
end

def self.entity_id(attribute_name=nil, &block)
self.custom_id_proc = if attribute_name != nil
->(capture) { capture.send(attribute_name.to_sym) }
elsif block_given?
block
else
raise ArgumentError.new('must provide an attribute name or a block')
end
end

expose :id, format_with: :to_string
expose :json_api_type, as: :type

Expand All @@ -24,6 +41,10 @@ def self.root(plural, singular = nil, for_real = false)

private

def id
self.class.custom_id_proc.is_a?(Proc) ? self.class.custom_id_proc.call(object) : object.id
end

# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity

def json_api_type
Expand Down
46 changes: 46 additions & 0 deletions spec/grape/jsonapi/entity/resource_identifier_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,50 @@ def json_api_type
end
end
end

context '#custom_id_proc' do
subject do
fresh_class.represent(data).serializable_hash
end

let(:record_id) { 'ID' }
let(:alternate_id_attribute) { 'ALT_ID_A' }
let(:alternate_id_block) { 'ALT_ID_B' }
let(:data) do
OpenStruct.new(
id: record_id,
other_attribute: alternate_id_attribute,
)
end

context 'when custom id is specified' do
let(:fresh_class) { Cow }

context 'as an attribute name' do
before { fresh_class.entity_id :other_attribute }

it 'uses the custom id' do
expect(subject[:id]).to eq alternate_id_attribute
end
end

context 'as a block' do
before { fresh_class.entity_id { |obj| alternate_id_block } }

it 'uses the custom id' do
expect(subject[:id]).to eq alternate_id_block
end
end

end

context 'when custom id is not specified' do
let(:fresh_class) { Mouse }

it 'uses the record id' do
expect(subject[:id]).to eq record_id
end
end

end
end