新手问题 SQLite3 数据库怎么保存数组类型?

msl12 · 2016年04月09日 · 最后由 msl12 回复于 2016年04月11日 · 9934 次阅读
class AddLikesCountAndLikedUserIdsToReplies < ActiveRecord::Migration
  def change
    add_column(:replies, :likes_count, :integer, default: 0)
    add_column(:replies, :liked_user_ids, :integer, default: [], array: true)
  end
end

我想通过上面这段代码将 liked_user_ids 字段保存为数组 Array 类型,结果

create_table "replies", force: :cascade do |t|
   t.integer  "user_id",                    null: false
   t.integer  "plan_id",                    null: false
   t.text     "body",                       null: false
   t.datetime "created_at",                 null: false
   t.datetime "updated_at",                 null: false
   t.integer  "likes_count",    default: 0
   t.integer  "liked_user_ids" # 这里并没有反应
 end

怎么解决呢?

网上查了下, https://github.com/rails/rails/issues/10432 这里似乎也有同样问题的人

不支持,只有 NULL, INTEGER, REAL, TEXT, BLOB 五种 https://www.sqlite.org/datatype3.html

Sqlite 和 MySQL 数据库本身都不支持,需要在 model 里面 serialize: http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize 本质上是 text 字段,存取的时候做 json 的转化。

你看的那个问题是 PostgreSQL 的,PostgreSQL 靠插件可以支持 json, array 等类型,而且速度快。

#3 楼 @billy 只能用 serialize 这个来实现存放数组的功能么

ruby-china 源码里有:

create_table "topics", force: :cascade do |t|
    t.integer  "user_id",                               null: false
    t.integer  "node_id",                               null: false
    t.string   "title",                                 null: false
    t.text     "body",                                  null: false
    t.text     "body_html"
    t.integer  "last_reply_id"
    t.integer  "last_reply_user_id"
    t.string   "last_reply_user_login"
    t.string   "node_name"
    t.string   "who_deleted"
    t.integer  "last_active_mark"
    t.boolean  "lock_node",             default: false
    t.datetime "suggested_at"
    t.integer  "excellent",             default: 0
    t.datetime "replied_at"
    t.integer  "replies_count",         default: 0,     null: false
    t.integer  "likes_count",           default: 0
    t.integer  "follower_ids",          default: [],                 array: true
    t.integer  "liked_user_ids",        default: [],                 array: true # 这里可以将其保存为数组?
    t.integer  "mentioned_user_ids",    default: [],                 array: true
    t.datetime "deleted_at"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

#5 楼 @msl12 rubyChina 用的是 PostgreSQL,可以存数组。你也可以选择用 PostgreSQL。

SQLite3 数据库不支持 Array 数组类型,你可以利用自定义 Type 的方式来实现。

谢谢各位,我已经转使用 postgreSQL 数据库了!

需要 登录 后方可回复, 如果你还没有账号请 注册新账号