我有一个Damage
表,其中包含以下字段:
我想添加另一个字段来存储Damagepoints
,它们是JSON对象,如下所示:
{ top: 50, left: 100 }
上图和左图是图表上damagepoint
的坐标。用户使用Javascript添加/删除damagepoints
。
但是,我想在一个字段中存储这些damagepoints
的数组,如下所示:
@damage.damagepoints = [{left: 40, top: 99}, {left: 100, top: 35}, {left: 150, top: 95}]
我不想使用Damagepoint
表与has_many
关系执行此操作,因为对此的所有更改都将使用Javascript完成,如果Damagepoints
已创建或由用户删除,我只想从客户端传递更新的damagepoints
数组,并用新数组替换数据库中的旧数组。如果我使用了has_many
关系,我必须删除所有Damagepoints
并在每次更新数组时创建每个新关系(因为它太复杂并且没有删除/的好处添加特定的伤害点,因为我不需要跟踪历史记录。)
存储@damage.damagepoints
(上图)等数据的最简单方法是什么?我需要做的就是将它(通过控制器)传递给html5数据属性,以便Javascript可以使用它将现有的damagepoints
添加到图表中(基于它们的坐标),然后当用户单击“保存”按钮时,通过AJAX调用将更新的数组(从html5数据属性)传递回控制器。
我正在使用Rails 4.2和Postresql。
谢谢!
答案 0 :(得分:7)
当你使用postgres时,你很幸运:postgres有一个原生的json类型。这比使用序列化将数据存储为某种形式的编码字符串更好,因为postgres具有丰富的运算符系列,允许您查询该json数据。
如果您使用的是postgres 9.4,那么您也可以使用jsonb类型。这通常更好,因为它存储了一个处理过的数据版本(即它不必一遍又一遍地重新分析数据),它允许索引。
Rails支持开箱即用(请参阅here),您只需要添加json(b)类型的列。如果您的迁移包含
create_table :damages do |t|
t.string :description
t.jsonb :damage_points
end
然后
Damage.create(damage_points: [{left: 40, top: 99}, {left: 100, top: 35}])
会创建一个损坏点数据存储为json的行。唯一需要注意的是,尽管输入数据的符号是哈希中的键,但是当从数据库中获取时,您总是会将字符串作为键返回。
答案 1 :(得分:1)
在写入数据库之前序列化数据,并在读取时反序列化。您可以覆盖模型中的getter和setter。
序列化的两个好选项是JSON
和YAML
。
Rails附带json
gem,因此您只需在任何对象或数组上调用to_json
即可。然后你需要阅读它,JSON.parse(some_json)
。
同样,Rails附带yaml
,因此您可以使用YAML.dump(text)
和YAML.load(text)
。在我看来,YAML比JSON更具人性化,但如果你将数据传递给Javascript,JSON就是标准。