【问题标题】:How to keep array structure when saving record - activerecord/postgres保存记录时如何保持数组结构-activerecord/postgres
【发布时间】:2017-02-15 04:16:37
【问题描述】:

我创建了一个哈希数组结构,并在 postgres 中创建了一个列以使用下面的迁移来保存该结构

class AddKeyDirectionsToEvent < ActiveRecord::Migration[5.0]
  def change
    add_column :calendar_events, :key_directions, :text, array:true, default: []
  end
end

现在,数组的结构是下面那个

{
    :in => [
        [0] {
               :duration => "5 mins",
               :distance => "0.4 km",
            :travel_mode => "WALKING",
            :travel_type => nil
        },
        [1] {
               :duration => "12 mins",
               :distance => "5.3 km",
            :travel_mode => "TRANSIT",
            :travel_type => "SUBWAY"
        },
        [2] {
               :duration => "9 mins",
               :distance => "0.7 km",
            :travel_mode => "WALKING",
            :travel_type => nil
        }
    ]
}
{
    :out => [
        [0] {
               :duration => "10 mins",
               :distance => "0.7 km",
            :travel_mode => "WALKING",
            :travel_type => nil
        },
        [1] {
               :duration => "12 mins",
               :distance => "5.3 km",
            :travel_mode => "TRANSIT",
            :travel_type => "SUBWAY"
        },
        [2] {
               :duration => "6 mins",
               :distance => "0.4 km",
            :travel_mode => "WALKING",
            :travel_type => nil
        }
    ]
}

但由于某种原因在数据库中它是这样保存的

["{:in=>[{:duration=>\"5 mins\", :distance=>\"0.4 km\", :travel_mode=>\"WALKING\", :travel_type=>nil}, {:duration=>\"12 mins\", :distance=>\"5.3 km\", :travel_mode=>\"TRANSIT\", :travel_type=>\"SUBWAY\"}, {:duration=>\"9 mins\", :distance=>\"0.7 km\", :travel_mode=>\"WALKING\", :travel_type=>nil}]}", "{:out=>[{:duration=>\"10 mins\", :distance=>\"0.7 km\", :travel_mode=>\"WALKING\", :travel_type=>nil}, {:duration=>\"12 mins\", :distance=>\"5.3 km\", :travel_mode=>\"TRANSIT\", :travel_type=>\"SUBWAY\"}, {:duration=>\"6 mins\", :distance=>\"0.4 km\", :travel_mode=>\"WALKING\", :travel_type=>nil}]}"]

任何想法为什么?我尝试将数组类型从 :text 更改为 :varchar 并得到相同的结果。我找到的唯一解决方案是使用 eval 命令将字符串转换回数组,这并不理想。

【问题讨论】:

    标签: ruby-on-rails arrays postgresql activerecord


    【解决方案1】:

    您需要将列类型设置为 json。使用下面的迁移命令 -

    rails g migration AddKeyDirectionsToCalendarEvent key_directions:json
    

    像这样将你的结构转换为 ruby​​ 数组:

    data = [{
        :in => [
            {
                   :duration => "5 mins",
                   :distance => "0.4 km",
                :travel_mode => "WALKING",
                :travel_type => nil
            },
            {
                   :duration => "12 mins",
                   :distance => "5.3 km",
                :travel_mode => "TRANSIT",
                :travel_type => "SUBWAY"
            },
            {
                   :duration => "9 mins",
                   :distance => "0.7 km",
                :travel_mode => "WALKING",
                :travel_type => nil
            }
        ]
    },
    {
        :out => [
            {
                   :duration => "10 mins",
                   :distance => "0.7 km",
                :travel_mode => "WALKING",
                :travel_type => nil
            },
            {
                   :duration => "12 mins",
                   :distance => "5.3 km",
                :travel_mode => "TRANSIT",
                :travel_type => "SUBWAY"
            },
            {
                   :duration => "6 mins",
                   :distance => "0.4 km",
                :travel_mode => "WALKING",
                :travel_type => nil
            }
        ]
    }]
    

    那就做吧,

    event.key_directions=data
    event.save
    

    这样会保存在数据库中,

    [["updated_at", 2016-10-06 13:11:26 UTC], ["key_directions", "[{\"in\":[{\"duration\":\"5 mins\",\"distance\":\"0.4 km\",\"travel_mode\":\"WALKING\",\"travel_type\":null},{\"duration\":\"12 mins\",\"distance\":\"5.3 km\",\"travel_mode\":\"TRANSIT\",\"travel_type\":\"SUBWAY\"},{\"duration\":\"9 mins\",\"distance\":\"0.7 km\",\"travel_mode\":\"WALKING\",\"travel_type\":null}]},{\"out\":[{\"duration\":\"10 mins\",\"distance\":\"0.7 km\",\"travel_mode\":\"WALKING\",\"travel_type\":null},{\"duration\":\"12 mins\",\"distance\":\"5.3 km\",\"travel_mode\":\"TRANSIT\",\"travel_type\":\"SUBWAY\"},{\"duration\":\"6 mins\",\"distance\":\"0.4 km\",\"travel_mode\":\"WALKING\",\"travel_type\":null}]}]"], ["id", 4]]
    

    当你访问它时你会得到数组

        event.key_directions
    
     => [{"in"=>[{"duration"=>"5 mins", "distance"=>"0.4 km", "travel_mode"=>"WALKING", "travel_type"=>nil}, {"duration"=>"12 mins", "distance"=>"5.3 km", "travel_mode"=>"TRANSIT", "travel_type"=>"SUBWAY"}, {"duration"=>"9 mins", "distance"=>"0.7 km", "travel_mode"=>"WALKING", "travel_type"=>nil}]}, {"out"=>[{"duration"=>"10 mins", "distance"=>"0.7 km", "travel_mode"=>"WALKING", "travel_type"=>nil}, {"duration"=>"12 mins", "distance"=>"5.3 km", "travel_mode"=>"TRANSIT", "travel_type"=>"SUBWAY"}, {"duration"=>"6 mins", "distance"=>"0.4 km", "travel_mode"=>"WALKING", "travel_type"=>nil}]}] 
    

    【讨论】:

    • 刚刚试过这个并给了我这个PG::InvalidTextRepresentation: ERROR: invalid input syntax for type json DETAIL: Expected ":", but found ",". CONTEXT: JSON data, line 1: ...:travel_mode=&gt;\"WALKING\", :travel_type=&gt;nil}]}",... : UPDATE "calendar_events" SET "key_directions" = $1, "updated_at" = $2 WHERE "calendar_events"."id" = $3
    • 如果您在数据库中已经有该列的一些记录,您必须先删除它们。
    • 你能显示一个来自 schema.rb 的 sn-p,它有 create_table "events" do .. end
    • 刚刚添加,列名为key_directions
    • 我还添加了生成的 SQL
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    相关资源
    最近更新 更多