如何在葡萄实体宝石中定义动态密钥?

时间:2017-11-06 01:16:33

标签: ruby-on-rails grape grape-entity

假设我有一个User模型,我通过User公开了Grape::Entity个对象。所以在这里我想定义一个动态键,其名称及其值将基于其他键(idnameemail)值。

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

我怎么能这样做? 提前谢谢!

3 个答案:

答案 0 :(得分:1)

您可以使用object访问该实例:

def dynamic_key
  "#{object.id}_#{object.name}"
end

编辑:误解了这个问题。不要以为你可以通过这种方式获得动态密钥。你能做这样的事吗:

 expose "#{object.id}_#{object.name}".to_sym

答案 1 :(得分:0)

您为什么要这样做?如果您想要动态的东西,它应该是键映射到的 value ,而不是键本身。 API的使用者应该能够依赖与您所记录的定义一致的键名,并且还要记住,键的要点是要具有一个您可以一致引用的名称,该名称可以映射到动态值。因此,如果要使用动态生成的值公开某些dynamic_key属性,可以执行以下操作:

expose :id
expose :name
expose :email
expose :dynamic_key do |object, _options|
  "#{object.id}_#{object.name}"
end

哈希{ id: 1, name: 'Foo', email: 'foo@bar.done' }将表示为:

{ id: 1, name: 'Foo', email: 'foo@bar.done', dynamic_key: '1_Foo' }

答案 2 :(得分:0)

如果有人正在寻找解决方案,这就是我所做的:

origin/develop

结果是:

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

或者对于只有一个基于 id 和 name 的动态键的简单情况

{
  "id": 1,
  "first_key": "first_key value",
  "second_key": "second_key value",
  "third_key": "third_key value"
}