Rails jsonb - 当jsonb保存到Postgresql数据库时,防止JSON键重新排序

问题描述 投票:-1回答:2

我有一个列amount_splits,我需要按照我指定的密钥顺序保存我的JSON。

当我将其保存到数据库时,如何防止Rails / Postgres jsonb自动排序我的JSON密钥? (用于创建或更新)

看起来它正在尝试按字母顺序排序,但做得不好。

Here's what I'm saving:

{
    "str_fee": 3.17,       # key 1
    "eva_fee": 14.37,      # key 2
    "fran_royalty": 14.37, # key 3
    "fran_amount": 67.09   # key 4
}

This is how it actually saves:

{
    "eva_fee": 14.37,     # key 2
    "str_fee": 3.17,      # key 1
    "fran_amount": 67.09, # key 4
    "fran_royalty": 14.37 # key 3
}

Purpose:

在您回答“在接收端使用JSON时排序无关紧要”之前,请先停下来思考......请继续阅读

我需要按照我需要排序的方式对键进行排序,因为使用此JSON的客户端接口向开发人员显示JSON,这些开发人员需要按照文档告诉他们的顺序的键。以及它需要的原因按顺序显示首先在哪个顺序发生的计算过程:

正确的订单告诉开发人员:

首先应用str_fee,然后是eva_fee,然后是fran_royalty ......使fran_amount成为结束量。

但根据jsonb如何对此进行排序,它错误地告诉我们的开发人员:

首先应用eva_fee,然后是str_fee,然后是fran_amount ......使fran_royalty成为结束量。

ruby-on-rails json postgresql ruby-on-rails-5 jsonb
2个回答
0
投票

我找不到任何关于如何修改jsonb保存/更新行为的信息,但你可以控制如何从你的Rails模型中返回你的as_json

因此,不要通过直接调用self.amount_splits列返回您的JSON(它将以错误的键顺序返回)...手动分解每个键。

注意:这只有在您提前知道您的密钥名称时才有效...如果在您知道密钥名称之前动态创建密钥名称,则需要尝试其他内容...可能将您的JSON保存为字符串而不是哈希。

class Transaction < ApplicationRecord
  store_accessor :amount_splits, :str_fee, :eva_fee, :fran_royalty, :fran_amount

  [...]

  def as_json(options={})
    # simple JSON response:
    json = {
      [...]
      "amount_splits"   => {
        "str_fee"       => self.str_fee,
        "eva_fee"       => self.eva_fee,
        "fran_royalty"  => self.fran_royalty,
        "fran_amount"   => self.fran_amount
      },
      [...]
    }
    return json
  end

  [...]

end

注意:我已经明显缩写了我的自定义as_json方法,只留下它将返回的JSON的相关部分


0
投票

实际上它们不是按字母顺序排序,而是按键长度排序,然后按字母顺序排序,这解释了你得到的顺序。 jsonb类型已被创建为json类型的更好版本以编写和访问数据,它可能用于索引和搜索目的,它们更改键顺序。如果您希望键顺序不要更改,则可以使用json类型,该类型在数据库中存储数据时不会更改键的顺序。

希望能帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.