2016-06-23 12 views
6

は、私は列にjsonbデータ型を使用したモデルProjectKeywordを: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)>' 

しかし、更新する前にフィールドsegmented_datahashの値を設定すると、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のデフォルト値を作成する方法です。

+0

これを試しましたか?http://stackoverflow.com/a/20746242/3884750? –

+0

はい、私は試しました、それは動作しません –

答えて

12

これは、いくつかのプロジェクトで私のために働いています

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

(文字列ではありません、ルビーハッシュ)

を、私は、これはRailsの3に取り組んでいない思い出すように見えるが、それはでは問題ないはずですRails 4.

+0

細かいレール4 - そしてまた5レールです。 –