简体   繁体   中英

A rails field that is an array of JSON objects?

I have a Damage table that has the following fields:

  • description
  • date_of_damage

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

{ 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.

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).

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.

I am using Rails 4.2 and Postresql.

Thanks!

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.

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 (ie it doesn't have to keep reparsing the data over and over again) and it allows indexes.

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

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.

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

Two good options for serialization would be JSON and 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) .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM