Railsアプリで、ハッシュマッピングIDをいくつかの試行に保存しようとしています。この新しい列に対応するためのデータベースへの移行:
class AddMultiWrongToUser < ActiveRecord::Migration
def self.up
add_column :users, :multi_wrong, :string
end
def self.down
remove_column :users, :multi_wrong
end
end
私のモデルでは:
class User < ActiveRecord::Base
serialize :multi_wrong, Hash
end
ただし、Railsコンソールを使用してこれをテストするには、次のようにします。
user = User.create()
user.multi_wrong = {"test"=>"123"}
user.save
出力は偽です。ここで何が問題になっていますか?
列のタイプが間違っています。文字列の代わりにテキストを使用する必要があります。したがって、移行は次のようになります。
def self.up
add_column :users, :multi_wrong, :text
end
その後、Railsはそれを適切にYAMLに変換します(そして適切なシリアル化を実行します)。文字列フィールドのサイズには制限があり、特に小さい値のみが保持されます。
更新:
正確な実装はデータベースに依存しますが、PostgreSQLにはjson
およびjsonb
列があり、ハッシュ/オブジェクトデータをネイティブに保存して、 ActiveRecordでJSONに対してクエリ !
移行を変更すれば完了です。
class Migration0001
def change
add_column :users, :location_data, :json, default: {}
end
end
オリジナル:
詳細:Rails docs (&&apidock
列が:text
ではなく:string
であることを確認してください
移行:
$ Rails g migration add_location_data_to_users location_data:text
作成する必要があります:
class Migration0001
def change
add_column :users, :location_data, :text
end
end
あなたのクラスは次のようになります:
class User < ActiveRecord::Base
serialize :location_data
end
利用可能なアクション:
b = User.new
b.location_data = [1,2,{foot: 3, bart: "noodles"}]
b.save
もっと素晴らしい?!
postgresql hstoreを利用する
class AddHstore < ActiveRecord::Migration
def up
enable_extension :hstore
end
def down
disable_extension :hstore
end
end
class Migration0001
def change
add_column :users, :location_data, :hstore
end
end
hstoreを使用すると、シリアル化されたフィールドに属性を設定できます
class User < ActiveRecord::Base
# setup hstore
store_accessor :location_data, :city, :state
end
Rails 4には Store と呼ばれる新しい機能があり、問題を解決するために簡単に使用できます。アクセサを定義できます。シリアル化されたストアに使用されるデータベース列をテキストとして宣言することをお勧めします。そのため、十分なスペースがあります。元の例:
class User < ActiveRecord::Base
store :settings, accessors: [ :color, :homepage ], coder: JSON
end
u = User.new(color: 'black', homepage: '37signals.com')
u.color # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
# There is no difference between strings and symbols for accessing custom attributes
u.settings[:country] # => 'Denmark'
u.settings['country'] # => 'Denmark'