Reputation: 651
Lets say I have a User
model and I am exposing User
object via Grape::Entity
. So in here I want to define a dynamic key which name and its value will be based on other keys(id
, name
, email
) value.
module API
module Entities
class User < Grape::Entity
expose :id
expose :name
expose :email
expose :dynamic_key # dynamic key name will be generated based on other keys(`id`, `name`, `email`) value
private
def dynamic_key
#dynamic key value here based on other keys(`id`, `name`) value
end
end
end
end
How could I do it? Thanks in advance!
Upvotes: 0
Views: 1278
Reputation: 366
If someone is looking for a solution, this is what I do :
class Trucs < Grape::Entity
expose :id
# expose custom / dynamic fields
expose :details, merge: true # merge true to avoid "details": {...} in response
private
def details
details_list = {}
list_of_fields = %w[first_key second_key third_key] # keys can be dynamically created, this is just a sample.
list_of_fields.each do |field_name|
details_list[field_name.to_sym] = "#{field_name} value" # OR object.send(field_name) OR anythig you need
end
return details_list
end
end
Result is :
{
"id": 1,
"first_key": "first_key value",
"second_key": "second_key value",
"third_key": "third_key value"
}
Or for a simple case with just one dynamic key based on id and name
def details
{"#{object.id}_#{object.title}": 'my dynamic value'}
end
Upvotes: 1
Reputation: 2333
Why would you want to do this? If you want something dynamic, it should be the value the key maps to -- not the key itself. The consumer of your API should be able to depend on the key names being consistent with your documented definitions, and also keep in mind that the point of keys is to have a name you can consistently reference that maps to a dynamic value. So if you want to expose some dynamic_key
attribute with a dynamically generated value, you can do this:
expose :id
expose :name
expose :email
expose :dynamic_key do |object, _options|
"#{object.id}_#{object.name}"
end
The hash { id: 1, name: 'Foo', email: '[email protected]' }
would be represented as:
{ id: 1, name: 'Foo', email: '[email protected]', dynamic_key: '1_Foo' }
Upvotes: 0
Reputation: 3298
You have access to the instance with object
:
def dynamic_key
"#{object.id}_#{object.name}"
end
Edit: misunderstood the question. Don't think you can get the dynamic key this way. Can you just do something like this:
expose "#{object.id}_#{object.name}".to_sym
Upvotes: 1