Railsモデルで、jsonタイプのデータベース列があります:
create_table "games", force: true do |t|
t.json "game_board"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
すごい!どうすれば使用できますか? フィールドをHash
のように扱うのと同じくらい簡単ですか?
self.game_board[:player1] = 1
self.game_board[:cards] = cards.to_hash
私がそれを書いた場合、すべてが期待どおりに機能するので、クライアントからの将来のAPI呼び出しでこれを行うことができますか?:
self.game_board[:player] # And get back the 1 that I put here before
パフォーマンスについてもどうですか?全体game_board
そのフィールドが読み込まれない場合でも毎回デシリアライズされますか? 「ハッシュ」の一部を変更するたびにフィールドは書き換えられますか(IOWデータベースの書き込み)。
はい、ActiveRecordはPostgresのjson
- fieldsを単にモデルのハッシュとして使用することを許可しています。ただし、考慮すべき点がいくつかあります。
初期化時にハッシュがNULLになる可能性がありますcreate_table
の移行では、フィールド:game_board
をNULL
にすることができます。したがって、最初の使用時には、モデルインスタンスのフィールド:game_board
はNULL
になり、使用する前にハッシュを初期化する必要があります。 (下の例を参照)
JSONでは、すべてのキーは文字列です
したがって、以前に記号または数値を使用したことがある場合、保存(および再ロード)時にすべてのキーが文字列に変換されます。したがって、ORMがすべてのキーをシンボル化するように構成されていない限り、不要な動作を防ぐために文字列キーを使用することをお勧めします。
あなたの例:
self.game_board ||= {}
self.game_board[:player1] = 1
self.game_board[:cards] = cards.to_hash
# after reload from database (access via String-key):
self.game_board['player1'] # And retrieve value 1 (that we put here before)
@パフォーマンス:
はい、ActiveRecordがデータベースからエントリを読み取ってモデルインスタンスを作成するたびに、JSONフィールドはハッシュ化されてハッシュに変換されます。しかし、それがアプリケーションのパフォーマンスに影響を与えると考える場合は、テキストフィールドを使用してJSON/Hashesをシリアル化/逆シリアル化する必要があるか、またはさらに良いことに、ActiveRecordを使用しないでください。クラスのヒープを作成し、magic-methodsを使用することにより、ActiveRecordは、JSONの逆シリアル化について心配する必要がないほどのオーバーヘッドを作成します。利便性にはコストがかかります。
はい、ハッシュの値を変更するたびに、(全体の)JSONフィールドは新しいシリアル化されたバージョンに置き換えられ、更新されます。
これに関する2つのメモ:
さらに明確にするために-JSONオブジェクトをモデルインスタンスの属性に保存する場合必ずハッシュとして保存してください。
JSONstringの解析を忘れても、Active Recordは文句を言いません:
_ game = Game.create(game_board: '"key":"value"')
_
json
属性から文字列を取得する場合、文句はなく、文字列を返すだけです。
_ game.game_board
=> '"key":"value"'
_
したがって、ストリングをハッシュのように処理しようとしているため、_game.game_board['key']
_はエラーになります。
そのため、保存する前に必ずJSON.parse(string)
を使用してください。
_ game = Game.create(game_board: JSON.parse('"key":"value"'))
_
だから今あなたは期待された行動を持っています
_game.game_board['key']
=> 'value'
_
おそらくこの場合は役に立ちませんが、統合しているAPIからJSONペイロードを保存するときにこの問題に遭遇しました。とにかく、これが役に立てば幸いです。