0
module Entities
  class StuffEntity < Grape::Entity
    root 'stuffs', 'stuff'
    ...

我怎样才能通过重用这个实体来干燥我的代码,同时仍然可以灵活地重命名实体中定义的根键('stuffs'和'stuff')?

在公开由现有实体表示的集合的子集或公开可由现有实体表示的关联集合的情况下,我可能需要执行此操作。

4

1 回答 1

0

公开关联对象或集合时隐藏根键

假设我有一个具有name属性的对象和一些scoped_stuff我想公开为some_stuffs. 我可以用这样的实体做到这一点:

module Entities
  class CoolStuffEntity < Grape::Entity
    root 'cool_stuffs', 'cool_stuff'
    
    expose :some_stuffs, documentation: {
      type: Entities::StuffEntity
    } do |object, _options|
      Entities::StuffEntity.represent(
        object.class.scoped_stuff,
        root: false
      )
    end
    
    expose :name, documentation: { type: 'string' }
  end
end

传递root: false给该represent方法可确保嵌套关联在没有根键的情况下表示。以下是带有和不带有该参数的表示形式:

# Without root: false
cool_stuff: {
  some_stuffs: { 
    stuffs:    [ /* collection represented by StuffEntity */ ] 
  },
  name: 'Something'
}

# With root: false
cool_stuff: { 
  some_stuffs: [ /* collection represented by StuffEntity */ ],
  name:        'Something'
}

在这种情况下,传递root: false确保嵌套实体的根键不包含在我们的表示中。

在呈现没有定义根的实体时设置根键名称

假设我们有一个没有指定根的实体:

module Entities
  class StuffEntity < Grape::Entity
    expose :name, documentation: { type: 'string' }
  end
end

用此实体表示的对象的可序列化哈希将如下所示:{ name: 'Object name' }

在我们的 API 中,我们可以像这样指定响应密钥:

get do
  stuff_object = Stuff.find_by(user_id: current_user)

  present stuff_object, 
    with: Entities::StuffEntity,
    root: :stuff
end

这样我们的响应将如下所示:{ stuff: { name: 'Object name' } }

请注意,“root”在此处接受字符串和符号参数。

如果要重命名 API 响应中的根密钥

那么,如果我有一个指定了根键的实体,并且我希望我的响应中的键不同(例如,公开集合的子集)怎么办?present我可以再次使用,而不是使用represent。除了这一次,我可以给它一个键名,而不是通过传递'false'来禁用根键:

get do
  my_stuff = Stuff.find_by(user_id: current_user)

  Entities::StuffEntity.represent(
    my_stuff,
    root: :my_stuff
  )
end
于 2020-09-03T22:19:28.610 回答