ruby on rails jsonb 列默认值

Posted

技术标签:

【中文标题】ruby on rails jsonb 列默认值【英文标题】:ruby on rails jsonb column default value 【发布时间】:2016-10-25 12:20:26 【问题描述】:

我有一个模型 ProjectKeyword,我在 :segemnted_data 列中使用 jsonb 数据类型

class ProjectKeyword < ApplicationRecord
  belongs_to :project
  belongs_to :keyword
  has_many :project_keyword_dimensions
  has_many :dimensions, through: :project_keyword_dimensions

  validates :project_id, :keyword_id, presence: true
end

迁移

class AddSegemtnedDataToProjectKeywords < ActiveRecord::Migration[5.0]
  def change
    add_column :project_keywords, :segmented_data, :jsonb, default: ''
    add_index  :project_keywords, :segmented_data, using: :gin
  end
end

我的问题是当我创建新的 project_keyword 实例时,segmented_data 的默认值是字符串而不是哈希,我无法更新此字段或与另一个哈希合并 例如

[12] pry(#)> new_pr_keyword = ProjectKeyword.new(project_id: 1671333, keyword_id: 39155)
=> #<ProjectKeyword:0x007fd997641090 id: nil, project_id: 1671333, keyword_id: 39155, segmented_data: "">
[13] pry(#)> new_pr_keyword.save!
=> true
[14] pry(#)> new_pr_keyword.segmented_data.update('new_data' => 'some_data')
NoMethodError: undefined method `update' for "":String
from (pry):14:in `block (3 levels) in <top (required)>'

但是当我在更新之前将hash 值分配给字段segmented_data 时,update 方法可以正常工作。

例如

[15] pry(#)> new_pr_keyword.segmented_data = 'new_data' => 'some_data'
=> "new_data"=>"some_data"
[16] pry(#)> new_pr_keyword.save!
=> true
[17] pry(#)> new_pr_keyword.segmented_data.update('new_data_2' => 'some_data_2')
=> "new_data"=>"some_data", "new_data_2"=>"some_data_2"
[18] pry(#)> new_pr_keyword.save!
=> true

问题是如何将 segmented_data 的默认值设置为 Hash 类而不是 String,以便在刚刚创建对象后,方法更新将立即在该字段上起作用。

【问题讨论】:

你试过这个***.com/a/20746242/3884750 吗? 是的,我试过了,还是不行 【参考方案1】:

这在几个项目中对我有用:

add_column :project_keywords, :segmented_data, :jsonb, default: 

(不是字符串,是 ruby​​ 哈希)

我似乎记得这不适用于 Rails 3,但在 Rails 4 中应该没问题。

【讨论】:

在 Rails 4 中很好 - 在 Rails 5 中也是如此。 Fine on Rails 6 :) Rails >= 5 强制使用default: 。 edgeguides.rubyonrails.org/…

以上是关于ruby on rails jsonb 列默认值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用链接/按钮更改列属性 - Ruby on Rails

Ruby on Rails:如何使用迁移向现有列添加非空约束?

Ruby on rails:仅从两列范围内获取数据

如何在 ruby​​ on rails 中使每个 user_id 的列数据唯一

如何在 Ruby on Rails 迁移中使列唯一并为其编制索引?

Ruby on Rails 上“...的预期字符串默认值”的含义