如何解决Rails 从数据库转换变量名和值
我想在类的属性中使用转换后的名称/值,而不是我们从数据库中获得的。我需要这个的原因是我有两个版本的应用程序指向同一个数据库,但较新的版本最近更新了列名。因此,对于所有使用旧版本的应用,必须使其兼容。
Environment: Rails version: 6.0.3.3 & Ruby version: ruby 2.7.1p83
假设有一个名为 Sprinter 的类。 Sprinter 表看起来像:
id | 名称 | m | s |
---|---|---|---|
1 | 先生。螺栓 | 100 | 9.58 |
Sprinter 实例如下所示:
sprinter = {
"id" => 1,"name" => "Mr. Bolt","m" => 100,"s" => 9.58
}
旧版本需要不同的格式。现在我想要类似的东西:
sprinter = {
"id" => 1,"cm" => 10000,# transformed from `m`
"ms" => 9580 # transformed from `s`
}
m
列名称已转换为 cm
,值也已转换。 s
到 ms
的情况相同。值转换没什么大不了的,但变量名似乎是。
我更喜欢在获取对象时进行内部更新。但是,如果不支持,作为基本级解决方案,我更愿意更改发送给客户端的 json 表示。作为参考,我将其用作嵌套 include
的一部分,例如:
render status: :ok,json: {races: races}.as_json(
{:include => [:sprinters] }
)
谢谢。
解决方法
不用纠结于 .as_json
的内部结构或模型如何进行序列化,您可以使用序列化层来处理模型在 JSON 中的不同表示。
例如,如果您愿意,您可以使用 ActiveModel::Serializers 或 JBuilder,甚至可以自己使用。
module API
module V2
class SprinterAdapter
def intialize(sprinter)
@sprinter = sprinter
end
def to_json
@sprinter.to_json.except("m","s").merge(
"cm" => @sprinter.m * 100,"ms" => @sprinter.s * 1000
)
end
end
end
end
并且在您的控制器中,您将使用序列化程序来呈现资源:
module API
module V2
class SprintersController < ApplicationController
def show
@sprinter = Sprinter.find(params[:id])
render json: SprinterAdapter.new(@sprinter)
end
end
end
end
见:
,您可以通过 Sprinter
中的 select 转换键/值:
Sprinter.select(:id,:name,'m * 100 AS cm','s * 1000 AS ms')
但不确定如何将其与 as_json
结合版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。