ruby on rails значение столбца jsonb по умолчанию

У меня есть модель ProjectKeyword, где я использую тип данных jsonb в столбце :segemnted_data

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, чтобы обновление метода сразу же работало в этом поле после того, как объект был только что был создан.


person arthur-net    schedule 23.06.2016    source источник
comment
вы пробовали ЭТО stackoverflow.com/a/20746242/3884750?   -  person Oleg Sobchuk    schedule 23.06.2016
comment
Да, пробовал, не работает   -  person arthur-net    schedule 23.06.2016


Ответы (1)


Это сработало для меня в нескольких проектах:

add_column :project_keywords, :segmented_data, :jsonb, default: {}

(не строка, а рубиновый хеш)

Я припоминаю, что это не работает в Rails 3, но в Rails 4 должно быть нормально.

person Paul A Jungwirth    schedule 24.06.2016
comment
Fine in Rails 4 - А также в Rails 5. - person Frederik Spang; 10.08.2017
comment
Отлично на Rails 6 :) - person localhostdotdev; 07.04.2019