🐰
【Dynamoid で STI】複数のクラスを一つのテーブルにまとめる
Ruby on Rails で DynamoDB を ActiveRecord のように扱える Dynamoid を使用しています。
Users テーブルに以下のようなアイテムが入っていたとき、Rails 側で Users クラスとして取り扱うのが少し複雑になりそうだったので、なんとかならないかと思い調べました。
pk | sk | 説明 |
---|---|---|
U_#id | item_#item_id1 | ユーザー保持アイテム |
U_#id | item_#item_id2 | ユーザー保持アイテム |
U_#id | skill_#skill_id1 | ユーザースキル |
U_#id | skill_#skill_id2 | ユーザースキル |
U_#id | weakpoint | 弱点 |
要約
- STI(単一テーブル継承)を使う
- model に type field を追加する
STI(単一テーブル継承)を使う
STI とは Single Table Inheritance の略で単一テーブル継承の略だそうです。
もともとは、一つのテーブルから複数種類のクラスを扱うために ActiveRecord で用意されていた仕組みですが、Dynamoid でも同じ仕組みが用意されています。
model に type field を追加する
使い方は単純に model に type フィールドを追加するだけです。
class User
include Dynamoid::Document
table name: :user, key: :pk, read_capacity: 5, write_capacity: 5
range :sk, :string
field :type # <- これをついかする
end
class UserItem < User
field :item_id, :string
field :item_name, :string
end
class UserSkill < User
field :skill_id, :string
field :skill_name, :string
field :damage_alg, :string
end
inheritance_field: で競合を回避
既に type field がテーブルに存在している場合などで type field を使用したくない場合は、inheritance_field: で回避することができます。
class User
include Dynamoid::Document
table name: :user, key: :pk, inheritance_field: :sti_type
range :sk, :string
field :sti_type, :string
end
class UserItem < User
field :item_id, :string
field :item_name, :string
end
class UserSkill < User
field :skill_id, :string
field :skill_name, :string
field :damage_alg, :string
end
最後に
ドキュメントを見ればすぐにわかることですが、STI からのつながりを理解するためにまとめました。
DynamoDB では今回の例のように、一つのテーブルでいろいろなタイプのアイテムを格納することが多いので、STI を用いるのが効果的でよく使うことになりそうです。
参考
Discussion