ActiveModel序列化程序中的动态根密钥

时间:2017-10-23 13:20:28

标签: ruby-on-rails serialization ruby-on-rails-5 active-model-serializers

我在项目中使用Rails 5Acive Model Serializer (0.10.6)。我需要以下格式的JSON

{
   "account_lists": {
    "0": {
            "id": 1,
            "description": "test tets test tets"
          },
     "1": {
            "id": 2,
            "description": "test tets test tets"
          }
      }
}

01个键将是对象的索引。

我尝试使用下面的代码,但结果不会出现

account_serializer.rb

class AccountSerializer < ActiveModel::Serializer
  attributes :custom_method

  def custom_method
    { object.id => {id: object.id, description: object. description } }
  end
end

accounts_controller.rb

render json: @accounts, root: "account_lists", adapter: :json

结果是

{
"account_lists": [
    {
        "custom_method": {
            "46294": {
                "id": 46294,
                "description": "test tets test tets"
            }
        }
    },
    {
        "custom_method": {
            "46295": {
                "id": 46295,
                "description": "test tets test tets"
            }
        }
   ]
 }

请你帮我看看结果。

1 个答案:

答案 0 :(得分:3)

您可以通过两种方式实现此目的,使用序列化程序或不使用序列化程序。

为了使这与串行器一起工作,我们需要编写一些元编程。像这样的东西

class AccountSerializer < ActiveModel::Serializer
    attributes

    def initialize(object, options = {})
        super
        self.class.send(:define_method, "#{object.id}") do
            {
                "#{object.id}": {
                    id: object.id,
                    description: object.description
                }
            }
        end
    end

    def attributes(*args)
        hash = super
        hash = hash.merge(self.send("#{object.id}"))
    end
end

这将产生这样的结果

{
    "account_lists": [
        {
          "19":{
              "id":19,
              "description":"somethign here "
            }
        },
        {
            "20":{
                "id":20,
                "description":"somethign here "
            }
        },{
            "48":{
                "id":48,
                "description":"somethign here"
            }
        }
    ]
}

如果你想让json对你提到的问题做出正确反应,你最好选择一个为你构建json的自定义库类

class BuildCustomAccountsJson

  def initialize(accounts)
    @accounts = accounts
  end

  def build_accounts_json(accounts)
    _required_json = {}

    @accounts.map do |account|
     _required_json["#{account.id}"] = { id: "#{account.id}", description: "#{account.description}" }
    end

    _required_json
  end

end

在控制器操作中,我们可以使用此类

def index
  ...
  ...

  @accounts_json = BuildCustomAccountsJson.new(@accounts).build_accounts_json

  render json: @accounts_json, root: "accounts_list"
end 

这将产生像这样的json

{
   "account_lists": {
    "0": {
            "id": 1,
            "description": "test tets test tets"
          },
     "1": {
            "id": 2,
            "description": "test tets test tets"
          }
      }
}

就是这样。