skp*_*rin 7 postgresql json ruby-on-rails jsonb ruby-on-rails-5
我有一个列amount_splits,我需要按照我指定的键顺序将我的 JSON 保存到其中。
将jsonbJSON 键保存到数据库时,如何防止 Rails / Postgres自动对其进行排序?(用于创建或更新)
看起来它试图按字母顺序排序,但做得很差。
{
"str_fee": 3.17, # key 1
"eva_fee": 14.37, # key 2
"fran_royalty": 14.37, # key 3
"fran_amount": 67.09 # key 4
}
Run Code Online (Sandbox Code Playgroud)
{
"eva_fee": 14.37, # key 2
"str_fee": 3.17, # key 1
"fran_amount": 67.09, # key 4
"fran_royalty": 14.37 # key 3
}
Run Code Online (Sandbox Code Playgroud)
在您回答“在接收端消耗 JSON 时排序无关紧要”之前,请先停下来想一想……然后请继续阅读
我需要按照我需要的方式对键进行排序,因为使用此 JSON 的客户端界面正在向开发人员显示 JSON,这些开发人员需要按照文档告诉他们的顺序来显示 JSON。以及它需要的原因按照这个顺序是首先显示什么计算发生的过程:
正确的顺序告诉开发者:
首先str_fee应用 ,然后应用eva_fee,然后是fran_royalty... 制作fran_amount结束金额。
但是根据jsonb排序方式,它错误地告诉我们的开发人员:
首先eva_fee应用 ,然后应用str_fee,然后是fran_amount... 制作fran_royalty结束金额。
小智 15
实际上,它们不是按字母顺序排序,而是按密钥长度然后按字母顺序排序,这解释了您得到的顺序。该jsonb类型已被创建为json用于写入和访问数据的类型的更好版本,并且它们更改键顺序可能是为了索引和搜索目的。如果你希望你的键顺序不改变,你可以使用json在数据库中存储数据时不改变键顺序的类型。
希望能帮助到你。
[更新于 2021/02/12]请参阅下面我的“已接受”答案的评论@mu is too short(我不想接受我自己的答案,因为它是 Rails hack)。
基本上为了保存列中的顺序jsonb,我需要使用一个数组(即[{str_fee: 6}, {eva_fee: 11}, ...])。
[老套路答案]
我找不到有关如何修改jsonb保存/更新行为的任何信息,但您可以控制如何as_json从 Rails 模型返回。
因此,不要通过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
Run Code Online (Sandbox Code Playgroud)
注意:我已经显着缩写了我的自定义
as_json方法,只保留它将返回的 JSON 的相关部分
| 归档时间: |
|
| 查看次数: |
2700 次 |
| 最近记录: |