Created
December 14, 2017 14:06
-
-
Save IzumiSy/9325576ad7b569ad47e18e62bd902f2c to your computer and use it in GitHub Desktop.
ROM.rb relation example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "rom" | |
require "rom/sql" | |
# | |
# ## Relation | |
# | |
# RelationはROM.rbにおいてアダプタ固有の操作をラップする永続化レイヤの責務を扱う | |
# SQLiteやMySQL固有の操作はAdapterに実装されており、それらに対するインターフェースを提供する | |
# (余談ではあるが、rom-sqlは中のSQLビルダにSequelを使っている) | |
module Relations | |
class Users < ROM::Relation[:sql] | |
# schemaをROM::Relationの継承クラスの中で使うことでデータベースのスキーマを定義できる | |
# MySQLなどのデータベースを使っていれば、`schema(infer: true)`の一文でスキーマ推論を有効化できる | |
# ここではインメモリなので明示的にスキーマの定義をしている。 | |
schema(:users) do | |
attribute :id, Types::Int | |
attribute :name, Types::String | |
attribute :age, Types::Int | |
attribute :has_car, Types::Bool | |
end | |
# インスタンスメソッドを定義することで、Relationが持つメソッドを追加できる | |
# ここでは、Relationが対象としているアダプタ(例えばこのコードの場合はSQLite) | |
# に定義された固有の操作が行える。whereはSQLiteアダプタの中で定義されている。 | |
def all | |
where() | |
end | |
def has_car | |
where(has_car: true) | |
end | |
# デフォルトではすべてのカラムが返り値のレコードに含まれて返されるが | |
# それを変更したければdatasetを定義することができる。 | |
# この例の場合はhas_carを意図的にレコードに含めないようにしている。 | |
dataset do | |
select(:id, :name, :age) | |
end | |
end | |
end | |
# ROMを初期化して定義したRelationを登録する。 | |
# auto_registrationというディレクトリをまるごと登録対象にできるメソッドがあるので | |
# ちゃんとしたプロジェクトであればそちらをつかうのがよい。 | |
config = ROM::Configuration.new(:sql, "sqlite::memory") | |
config.register_relation(Relations::Users) | |
rom = ROM.container(config) | |
# データベースのテーブルがないのでマイグレーションをする | |
# こちらもちゃんとしたRakeタスクをROMが用意してくれているので | |
# まともなプロジェクトではこのようにマイグレーションを書くことはない。 | |
migration = ROM::SQL.migration(rom) do | |
change do | |
create_table(:users) do | |
primary_key :id | |
string :name | |
integer :age | |
boolean :has_car, default: false | |
end | |
end | |
end | |
gateway = rom.gateways[:default] | |
migration.apply(gateway.connection, :up) | |
# ROMに登録されたRelationを操作してみる。 | |
# Relationを経由すればinsertなどのSQLite固有のメソッドも使えるが、できればRelationのメソッド | |
# としてラップしたほうがよい。固有のメソッド以外にもoneやallなどのビルトインメソッドもある。 | |
users = rom.relations[:users] | |
users.insert(name: "Bob", age: 22, has_car: true) | |
users.insert(name: "Alice", age: 23) | |
p users.all.to_a # [{:id=>1, :name=>"Bob", :age=>22}, {:id=>2, :name=>"Alice", :age=>23}] | |
p users.has_car.to_a # [{:id=>1, :name=>"Bob", :age=>22}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment