Slide 1

Slide 1 text

Introduction to ROM Ginzarb 第38回 / @y-yagi

Slide 2

Slide 2 text

ROM ROM: Ruby Object Mapper DBのデータとRubyのobjectをマッピングする為のライブラリ Active Recordと異なりdatastoreはRDBMSに限定されない datastore毎にgemがある(RDBMS: rom­sql、MongoDB: rom­mongo等) datastoreはDBに限定されていない Gitを操作する為のrom­git、CSVを操作する為のrom­ csvなどもある

Slide 3

Slide 3 text

ROM 作者は 最近はdry­rbのcore developerもやってる romの内部でdry­rbが使われてる romとしての最初のリリースは 2013/5/31 プロトタイプは2012年に出来ていたらしい 最新バージョンは2.0.0 1.0.0の次に2.0.0までとんだ @solnic (Piotr Solnica)

Slide 4

Slide 4 text

Gems(adapter) rom-sql rom-yesql rom-http rom-couchdb rom-csv rom-yaml rom-cassandra rom-event_store

Slide 5

Slide 5 text

Gems(adapter) rom-git rom-in uxdb rom-json rom-kafka rom-mongo rom-neo4j rom-rethinkdb

Slide 6

Slide 6 text

Gems(other) rom-repository Repository(datastoreに対するオペレーション)用のgem rom-rails rom-roda

Slide 7

Slide 7 text

Gems 一覧上げてみたが、開発が止まってしまっているgemも割とあ る に 各adapterがrom 2.0に対応しているか、及び本番環境で使える状態かどうかの リストがある が、このリストも古いきが http://rom-rb.org/learn/getting-started

Slide 8

Slide 8 text

使い方

Slide 9

Slide 9 text

使い方 READING Repositoryを使用して読み込み処理を発行する Repositoryから更に各Adapterが提供するRelationを 経由して、datastoreから実際のデータの読み込みを行う WRITING Commandを使用して、データのCreate / Update / Deleteを 行う 各datastore固有の処理はRelationを経由して実行する

Slide 10

Slide 10 text

使い方(rom­sql) まずはmigration r e q u i r e ' r o m ­ r e p o s i t o r y ' r e q u i r e ' r o m ­ s q l ' # R O M : : C o n f i g u r a t i o n で接続先を指定 c o n f = R O M : : C o n f i g u r a t i o n . n e w ( : s q l , ' s q l i t e : : m e m o r y ' ) m i g r a t i o n = c o n f . g a t e w a y s [ : d e f a u l t ] . m i g r a t i o n d o c h a n g e d o c r e a t e _ t a b l e ( : u s e r s ) d o p r i m a r y _ k e y : i d c o l u m n : n a m e , S t r i n g , n u l l : f a l s e c o l u m n : e m a i l , S t r i n g , n u l l : f a l s e e n d e n d e n d # m i g r a t i o n 実行 m i g r a t i o n . a p p l y ( c o n f . g a t e w a y s [ : d e f a u l t ] . c o n n e c t i o n , : u p )

Slide 11

Slide 11 text

使い方(rom­sql) datastoreに対する処理を定義する為のRelationクラスを作成 c o n f = R O M : : C o n f i g u r a t i o n . n e w ( : s q l , ' s q l i t e : : m e m o r y ' ) # R e l a t i o n c l a s s U s e r s < R O M : : R e l a t i o n [ : s q l ] s c h e m a ( i n f e r : t r u e ) d e f b y _ i d ( i d ) w h e r e ( i d : i d ) e n d e n d # R O M : : C o n f i g u r a t i o n にR e l a t i o n を登録 c o n f . r e g i s t e r _ r e l a t i o n ( U s e r s ) # R O M : : C o n f i g u r a t i o n を使用してR O M : : C o n t a i n e r を作成する r o m = R O M . c o n t a i n e r ( c o n f )

Slide 12

Slide 12 text

使い方(rom­sql) データの操作を行う為のRepositoryクラスを作成 c l a s s U s e r R e p o < R O M : : R e p o s i t o r y [ : u s e r s ] c o m m a n d s : c r e a t e , u p d a t e : : b y _ i d , d e l e t e : : b y _ i d d e f [ ] ( i d ) u s e r s . b y _ i d ( i d ) . o n e ! e n d d e f a l l u s e r s . t o _ a e n d e n d

Slide 13

Slide 13 text

使い方(rom­sql) Repositoryを使用して、データの操作を行う # R O M : : C o n t a i n e r を使用してR e p o s i t o r y を作成 u s e r _ r e p o = U s e r R e p o . n e w ( r o m ) u s e r = u s e r _ r e p o . c r e a t e ( n a m e : ' J a n e ' , e m a i l : ' j a n e @ d o e . o r g ' ) p u t s u s e r . i n s p e c t # = > # < R O M : : S t r u c t [ U s e r ] i d = 1 n a m e = " J a n e " e m a i l = " j a n e @ d o e . o r g " > p u t s u s e r _ r e p o . a l l . i n s p e c t # = > [ # < R O M : : S t r u c t [ U s e r ] i d = 1 n a m e = " J a n e " e m a i l = " j a n e @ d o e . o r g " > ] u s e r _ r e p o . u p d a t e ( u s e r . i d , n a m e : ' J a n e D o e ' ) p u t s u s e r _ r e p o [ u s e r . i d ] . i n s p e c t # = > # < R O M : : S t r u c t [ U s e r ] i d = 1 n a m e = " J a n e D o e " e m a i l = " j a n e @ d o e . o r g " > u s e r _ r e p o . d e l e t e ( u s e r . i d )

Slide 14

Slide 14 text

使い方(rom­sql) ここまでのコードまとめ r e q u i r e ' r o m ­ r e p o s i t o r y ' r e q u i r e ' r o m ­ s q l ' # 接続先を指定 c o n f = R O M : : C o n f i g u r a t i o n . n e w ( : s q l , ' s q l i t e : : m e m o r y ' ) m i g r a t i o n = c o n f . g a t e w a y s [ : d e f a u l t ] . m i g r a t i o n d o c h a n g e d o c r e a t e _ t a b l e ( : u s e r s ) d o p r i m a r y _ k e y : i d c o l u m n : n a m e , S t r i n g , n u l l : f a l s e c o l u m n : e m a i l , S t r i n g , n u l l : f a l s e e n d e n d e n d # m i g r a t i o n 実行 m i g r a t i o n . a p p l y ( c o n f . g a t e w a y s [ : d e f a u l t ] . c o n n e c t i o n , : u p )

Slide 15

Slide 15 text

使い方 データの操作(CRUD)はRepositoryを使用して行う Repositoryは抽象的な操作のみ行い、datastoreに対する具 体的な処理はRelationで行う これは推奨されている(おそらく)だけで、実際はRepository を経由せずにRelationを直接使用する事も出来る Repositoryは抽象的な処理のみを行う事で、仮にdatastore が変わってもRelationを差し替えるだけで同じAPIを使用出 来る ようにしたいんだと思われる

Slide 16

Slide 16 text

使い方 デフォルトではdatastoreから取得したデータはROM::Struct クラスにマッピングされる 当然任意のクラスにデータをマッピングする事も可能 c l a s s U s e r a t t r _ r e a d e r : i d , : n a m e , : e m a i l d e f i n i t i a l i z e ( a t t r i b u t e s ) @ i d , @ n a m e , @ e m a i l = a t t r i b u t e s . v a l u e s _ a t ( : i d , : n a m e , : e m a i l ) e n d e n d u s e r _ r e p o . u s e r s . w h e r e ( n a m e : ' M a l c o l m ' ) . a s ( U s e r ) . t o _ a # = > [ # < U s e r : 0 x 0 0 5 5 8 d 6 b 7 6 2 f 2 0 @ e m a i l = " m a l c o l m @ e x a m p l e . c o m " , @ i d = 1 , @ n a m e = " M a l c o l m ]

Slide 17

Slide 17 text

romのcoreについて

Slide 18

Slide 18 text

RelationsとSchemas

Slide 19

Slide 19 text

Relations datastoreに対するread、及びwriteのAPIを提供する どのadapterを使用するかはRelation Classで定義する

Slide 20

Slide 20 text

Relations c l a s s U s e r s < R O M : : R e l a t i o n [ : s q l ] e n d 上記の場合 adapterにrom­sqlを使用する usersという名前のdatasetにアクセスする為のクラス になる

Slide 21

Slide 21 text

Relations rom­http adapterを使用する場合 c l a s s U s e r s < R O M : : R e l a t i o n [ : h t t p ] e n d

Slide 22

Slide 22 text

Schemas attributeの名前と型を定義する為の仕組み schemaはRelationクラスの中に定義する c l a s s U s e r s < R O M : : R e l a t i o n [ : h t t p ] s c h e m a d o a t t r i b u t e : i d , R O M : : T y p e s : : I n t a t t r i b u t e : n a m e , R O M : : T y p e s : : S t r i n g a t t r i b u t e : a g e , R O M : : T y p e s : : I n t e n d e n d

Slide 23

Slide 23 text

Schemas primary keyやforeign keyも使える c l a s s U s e r s < R O M : : R e l a t i o n [ : h t t p ] s c h e m a d o a t t r i b u t e : i d , R O M : : T y p e s : : I n t a t t r i b u t e : n a m e , R O M : : T y p e s : : S t r i n g a t t r i b u t e : a g e , R O M : : T y p e s : : I n t p r i m a r y _ k e y : i d e n d e n d c l a s s P o s t s < R O M : : R e l a t i o n [ : h t t p ] s c h e m a d o a t t r i b u t e : u s e r _ i d , R O M : : T y p e s : : F o r e i g n K e y ( : u s e r s ) e n d e n d

Slide 24

Slide 24 text

Schemas rom共通で使用出来る型はROM::Types namespaceで提供さ れている RDBMS固有の型等は別のnamespace(ex: ROM::SQL::Types::PG)で提供されている r e q u i r e ' r o m ­ s q l ' r e q u i r e ' r o m / s q l / t y p e s / p g ' c l a s s U s e r s < R O M : : R e l a t i o n [ : s q l ] s c h e m a d o a t t r i b u t e : m e t a , R O M : : S Q L : : T y p e s : : P G : : J S O N a t t r i b u t e : t a g s , R O M : : S Q L : : T y p e s : : P G : : A r r a y a t t r i b u t e : i n f o , R O M : : S Q L : : T y p e s : : P G : : H a s h e n d e n d

Slide 25

Slide 25 text

Schemas rom­sqlの場合、DBのtypeをそのまま使用する事も出来る primary keyやforeign keyの情報もそのまま反映される r e q u i r e ' r o m ­ s q l ' c l a s s U s e r s < R O M : : R e l a t i o n [ : s q l ] s c h e m a ( i n f e r : t r u e ) e n d

Slide 26

Slide 26 text

Schemas 型定義の為の処理には を使用している dry­typesについては前回の資料( )参照 dry-types Introduction_to_dry- rb

Slide 27

Slide 27 text

rom-sql

Slide 28

Slide 28 text

rom-sql RDBMSに対する処理を行う為のgem 実際のRDBMSへの処理には を使用している migration機能はSequelの機能をそのまま使っている Sequel: The Database Toolkit for Ruby

Slide 29

Slide 29 text

rom-sql associationsが使える belongs_to、has_many、has_many­ through、has_one、has_one­through c l a s s U s e r s < R O M : : R e l a t i o n [ : s q l ] s c h e m a ( i n f e r : t r u e ) d o a s s o c i a t i o n s d o h a s _ m a n y : t a s k s h a s _ o n e : a c c o u n t e n d e n d e n d

Slide 30

Slide 30 text

rom-sql データの取得はwhereで( ) コード r e q u i r e ' r o m ­ s q l ' c l a s s U s e r s < R O M : : R e l a t i o n [ : s q l ] s c h e m a ( i n f e r : t r u e ) d e f b y _ i d ( i d ) w h e r e ( i d : i d ) e n d e n d c o n t a i n e r = R O M . c o n t a i n e r ( : s q l , ' s q l i t e : : m e m o r y ' ) d o | c o n f | c o n f . d e f a u l t . c o n n e c t i o n . c r e a t e _ t a b l e ( : u s e r s ) d o p r i m a r y _ k e y : i d c o l u m n : n a m e , S t r i n g , n u l l : f a l s e c o l u m n : e m a i l , S t r i n g , n u l l : f a l s e e n d c o n f . r e g i s t e r _ r e l a t i o n ( U s e r s ) firstやlastなども使える

Slide 31

Slide 31 text

rom-sql Joinも使える c l a s s U s e r s < R O M : : R e l a t i o n [ : s q l ] d e f w i t h _ t a s k s i n n e r _ j o i n ( : t a s k s , u s e r _ i d : : i d ) e n d d e f w i t h _ p o s t s l e f t _ j o i n ( : p o s t s , u s e r _ i d : : i d ) e n d e n d

Slide 32

Slide 32 text

rom-sql 作成 / 更新 /削除はRelationを使用して行う 実際使用する場合は、Repositoryを経由し、Commandを使 用して処理を行う事が推奨されている(はず) c o n t a i n e r . r e l a t i o n s . u s e r s . i n s e r t ( n a m e : " M a l c o l m " , e m a i l : " m a l c o l m @ e x a m p l e . c o m " c o n t a i n e r . r e l a t i o n s . u s e r s . w h e r e ( i d : 1 ) . u p d a t e ( n a m e : " f i r s t " )

Slide 33

Slide 33 text

そもそもCommandとは何か

Slide 34

Slide 34 text

Command datastoreに対するcreate、update、delete処理を行うオブジ ェクトの事

Slide 35

Slide 35 text

Command rom­sqlのCreate Command r e q u i r e ' r o m / s q l / c o m m a n d s / e r r o r _ w r a p p e r ' r e q u i r e ' r o m / s q l / c o m m a n d s / t r a n s a c t i o n ' m o d u l e R O M m o d u l e S Q L m o d u l e C o m m a n d s # S Q L c r e a t e c o m m a n d # # @ a p i p u b l i c c l a s s C r e a t e < R O M : : C o m m a n d s : : C r e a t e a d a p t e r : s q l i n c l u d e T r a n s a c t i o n i n c l u d e E r r o r W r a p p e r u s e : a s s o c i a t e s u s e : s c h e m a

Slide 36

Slide 36 text

Command 普通にクラスなので、独自のCommandクラスを作成する事も可 能 c l a s s U p s e r t U s e r < R O M : : C o m m a n d s : : C r e a t e [ : s q l ] r e l a t i o n : u s e r s r e g i s t e r _ a s : u p s e r t d e f e x e c u t e # d o t h e o p e r a t i o n s t o c r e a t e a n e w r e c o r d o r u p d a t e a n e x i s t i n g o n e e n d e n d

Slide 37

Slide 37 text

romとRails

Slide 38

Slide 38 text

romとRails というgemがあり、それを使えばRailsでromを使える ようになっている rom-rails

Slide 39

Slide 39 text

romとRails rom用のinitializerを作成して、DBの接続先を指定する # c o n f i g / i n i t i a l i z e r s / r o m . r b R O M : : R a i l s : : R a i l t i e . c o n f i g u r e d o | c o n f i g | c o n f i g . g a t e w a y s [ : d e f a u l t ] = [ : s q l , E N V . f e t c h ( ' D A T A B A S E _ U R L ' ) ] e n d

Slide 40

Slide 40 text

romとRails migration用のtaskも提供されている * r a k e d b : c r e a t e _ m i g r a t i o n [ m i g r a t i o n _ n a m e ] * r a k e d b : m i g r a t e * r a k e d b : c l e a n * r a k e d b : r e s e t

Slide 41

Slide 41 text

romとRails 後は先ほどのサンプル同様RelationやRepositoryを定義す ればOK # a p p / r e l a t i o n s / u s e r s . r b c l a s s U s e r s < R O M : : R e l a t i o n [ : s q l ] e n d R O M . e n v . r e l a t i o n s [ : u s e r s ] # = > # < U s e r s d a t a s e t = # < S e q u e l : : S Q L i t e : : D a t a s e t : " S E L E C T * F R O M ` u s e r s ` " > >

Slide 42

Slide 42 text

romの今後

Slide 43

Slide 43 text

romの今後 7/27 に2.0.0がリリースされた Relationにschemaを定義する機能や、Repository経由で のCommand実行などの機能が入った PostgreSQLのUpsertのサポートも入った。PostgreSQLおし。 ROM - ROM 2.0.0 Released

Slide 44

Slide 44 text

romの今後 "Hanami and Trailblazer co-operation!" Hanami及びTrailblazerのコミュニティと連携するようにな ったとの事 hanami­modelのバックエンドにromが使うようにしたら、 romがReformの一緒に動作するようにするとのこと rom­sqlとrom­repositoryの安定版を年内に出す予定との 事 逆にいうとやはりまだ安定していない

Slide 45

Slide 45 text

まとめ ROMについて説明してみた まともにdocがあるのがrom­sqlだけで、他のadapterに関して はまともなdocが無い APIは整理されているようなのだが、それを説明しているdocが ないので、結局コードとテストを読む必要がある 一つの事をやるのに複数のやり方が出来てしまい、何が正し いやり方なのか正直わからなかった schemaの定義の仕方が、adapterのドキュメントによって微 妙に違ったり

Slide 46

Slide 46 text

まとめ rom­sqlと同じ使い方で他のdatastoreに対して処理が行える かと思ったが、割と駄目 gem側で機能が足りてない事が多い Commandが実装されてないとか、Schemaが実装されてな いとか割とある Readは出来るが、Writingが出来ないgemとかある まともに開発されているadapter、rom­sqlだけなのでは感 が

Slide 47

Slide 47 text

まとめ つらい

Slide 48

Slide 48 text

まとめ 正直な所、今使うべきではない感がある APIが気にいって使ってみたいと思うなら、積極的に開発に参 加していく位の心積もりが必要そう