Junan Chakma
Junan Chakma

Reputation: 651

How to define a dynamic key in grape-entity gem?

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

Answers (3)

LiKaZ
LiKaZ

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

Allison
Allison

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

EJAg
EJAg

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

Related Questions