一个JSON对象数组的rails字段?

时间:2021-05-08 13:20:50

I have a Damage table that has the following fields:

我有一个损坏表,它有以下字段:

  • description
  • 描述
  • date_of_damage
  • date_of_damage

I'd like to add another field to store Damagepoints, which are JSON objects that look like this:

我想添加另一个字段来存储damagepoint,它是如下所示的JSON对象:

{ top: 50, left: 100 }

Top and left are the coordinates of the damagepoint on a diagram. The damagepoints are added/removed by the user using Javascript.

上面和左边是图上的damagepoint的坐标。用户使用Javascript添加/删除损坏点。

However, I'd like to store, in one field, an array of these damagepoints, like this:

但是,我想在一个字段中存储这些损坏点的数组,如下所示:

@damage.damagepoints = [{left: 40, top: 99}, {left: 100, top: 35}, {left: 150, top: 95}]

I don't want to do this using a Damagepoint table with a has_many relationship because all of the changes to this will be done using Javascript, and if Damagepoints are created or removed by the user, I just want to pass from the client the updated array of damagepoints and replace the old one in the database with the new array. If I used a has_many relationship, I'd have to delete all of the Damagepoints and create each one new every time the array was updated (because it is too complicated and there is no benefit from deleting/adding specific damagepoints, as I don't need to track history).

我不想做这和has_many关系使用Damagepoint表,因为所有的更改,这将是使用Javascript完成的,如果Damagepoints创建或删除的用户,我想从客户端更新后的一系列Damagepoints和取代旧的数据库中的新数组。如果我使用has_many关系,我必须删除所有的Damagepoints并在每次更新数组时创建每一个新的(因为它太复杂了,删除/添加特定的Damagepoints没有好处,因为我不需要跟踪历史)。

What is the easiest way to store data like @damage.damagepoints (above)? All I need to do with it is pass it (via the controller) to an html5 data-attribute so that it can be used by the Javascript to add the existing damagepoints to the diagram (based on their coordinates) and then pass an updated array (from the html5 data-attribute) back to the controller via an AJAX call when the user clicks the 'Save' button.

存储数据最简单的方法是什么,比如@damage。damagepoints(上图)?所有我需要做的是通过它(通过控制器)一个html5数据属性,可以使用Javascript将现有damagepoints添加到图(根据他们的坐标),然后通过更新数组(从html5数据属性)回控制器通过一个AJAX调用当用户单击“保存”按钮。

I am using Rails 4.2 and Postresql.

我正在使用Rails 4.2和Postresql。

Thanks!

谢谢!

2 个解决方案

#1


6  

As you're using postgres, you're in luck: postgres has a native json type. This is way better than using serialize to store the data as some form of encoded string, because postgres has a rich family of operators that allow you to query against that json data.

在使用postgres时,您很幸运:postgres具有本机json类型。这比使用serialize将数据存储为某种形式的编码字符串要好得多,因为postgres拥有丰富的操作符系列,允许您查询json数据。

If you are using postgres 9.4 then you can also use the jsonb type. This is generally better as it stores a processed version of the data (i.e. it doesn't have to keep reparsing the data over and over again) and it allows indexes.

如果您正在使用postgres 9.4,那么您也可以使用jsonb类型。这通常更好,因为它存储了一个经过处理的数据版本(例如,它不必反复解析数据),并且它允许索引。

Rails supports this out of the box (see here), you just need to add a column of type json(b). If your migration contains

Rails从这个框中支持这个(参见这里),您只需要添加一个json类型的列(b)。如果迁移包含

create_table :damages do |t|
  t.string :description
  t.jsonb :damage_points
end

then

然后

Damage.create(damage_points:  [{left: 40, top: 99}, {left: 100, top: 35}])

would create a row with the damage points data store as json. The only thing to watch out for is that although your input data has symbols as the keys in the hashes, when fetching from the database you'll always get strings back as keys.

将使用损坏点数据存储为json创建一行。唯一要注意的是,尽管输入数据在散列中有符号作为键,但是当从数据库中提取时,始终会将字符串作为键返回。

#2


1  

Serialize your data before writing to the database and deserialize when reading. You can override the getter and setter in the model.

在写入数据库之前序列化数据,在读取时反序列化数据。可以重写模型中的getter和setter。

Two good options for serialization would be JSON and YAML.

序列化的两个好的选项是JSON和YAML。

Rails comes with the json gem so you can just call to_json on any object or array. Then you need to read it, JSON.parse(some_json).

Rails附带了json gem,因此您可以在任何对象或数组上调用to_json。然后需要读取它,JSON.parse(some_json)。

Similarly, Rails comes with yaml so you can use YAML.dump(text) and YAML.load(text). YAML is a little more human-readable than JSON in my opinion, but if you're passing the data to Javascript, JSON is the standard.

类似地,Rails附带了yaml,因此您可以使用yaml .dump(文本)和yaml .load(文本)。在我看来,YAML比JSON更具可读性,但如果您将数据传递给Javascript, JSON是标准。

#1


6  

As you're using postgres, you're in luck: postgres has a native json type. This is way better than using serialize to store the data as some form of encoded string, because postgres has a rich family of operators that allow you to query against that json data.

在使用postgres时,您很幸运:postgres具有本机json类型。这比使用serialize将数据存储为某种形式的编码字符串要好得多,因为postgres拥有丰富的操作符系列,允许您查询json数据。

If you are using postgres 9.4 then you can also use the jsonb type. This is generally better as it stores a processed version of the data (i.e. it doesn't have to keep reparsing the data over and over again) and it allows indexes.

如果您正在使用postgres 9.4,那么您也可以使用jsonb类型。这通常更好,因为它存储了一个经过处理的数据版本(例如,它不必反复解析数据),并且它允许索引。

Rails supports this out of the box (see here), you just need to add a column of type json(b). If your migration contains

Rails从这个框中支持这个(参见这里),您只需要添加一个json类型的列(b)。如果迁移包含

create_table :damages do |t|
  t.string :description
  t.jsonb :damage_points
end

then

然后

Damage.create(damage_points:  [{left: 40, top: 99}, {left: 100, top: 35}])

would create a row with the damage points data store as json. The only thing to watch out for is that although your input data has symbols as the keys in the hashes, when fetching from the database you'll always get strings back as keys.

将使用损坏点数据存储为json创建一行。唯一要注意的是,尽管输入数据在散列中有符号作为键,但是当从数据库中提取时,始终会将字符串作为键返回。

#2


1  

Serialize your data before writing to the database and deserialize when reading. You can override the getter and setter in the model.

在写入数据库之前序列化数据,在读取时反序列化数据。可以重写模型中的getter和setter。

Two good options for serialization would be JSON and YAML.

序列化的两个好的选项是JSON和YAML。

Rails comes with the json gem so you can just call to_json on any object or array. Then you need to read it, JSON.parse(some_json).

Rails附带了json gem,因此您可以在任何对象或数组上调用to_json。然后需要读取它,JSON.parse(some_json)。

Similarly, Rails comes with yaml so you can use YAML.dump(text) and YAML.load(text). YAML is a little more human-readable than JSON in my opinion, but if you're passing the data to Javascript, JSON is the standard.

类似地,Rails附带了yaml,因此您可以使用yaml .dump(文本)和yaml .load(文本)。在我看来,YAML比JSON更具可读性,但如果您将数据传递给Javascript, JSON是标准。