DataMapper が予想以上に賢すぎる
なんか DataMapper が予想以上に賢かったので紹介してみる。
$ merb -i
### IRB のエコーバックをオフにする
irb> %w[a] # エコーバックされる
=> ["a"]
irb> IRB.conf[:MAIN_CONTEXT].echo = false
irb> %w[a] # エコーバックされないことを確認
### すべての従業員オブジェクトを検索した時点では、
### まだ SQL は発行されない
irb> employees = Employee.all
### オブジェクトにアクセスしてから初めて SQL が発行される
irb> employees.each {|emp| p emp }
~ SELECT `id`, `name`, `department_id` FROM `employees` ORDER BY `id`
#<Employee id=1 name="Kathy" department_id=1>
#<Employee id=2 name="Mike" department_id=1>
#<Employee id=3 name="John" department_id=2>
#<Employee id=4 name="Bill" department_id=3>
### 関連するオブジェクトも、必要になった時点で初めて SQL が
### 自動的に発行される。あらかじめ取得されるわけではない。
irb> employees.each {|emp| p emp.department if false } # 発行されない
irb> employees.each {|emp| p emp.department } # 発行される
~ SELECT `id`, `name` FROM `departments` WHERE (`id` IN (3, 1, 2)) ORDER BY `id
#<Department id=1 name="Sales">
#<Department id=1 name="Sales">
#<Department id=2 name="Marketing">
#<Department id=3 name="Development">
Employee.all の時点ではまだ SQL は実行されないのか。知らんかったわ。
なんか思ってた以上に凝ったことをしていて驚いてるんだけど、きっと最近の O/R Mapper はこんな感じなんだろうな。詳しくは知らんけど、Python の SQLAlchemy とかそんな気がする。
なお IRB のエコーバックを off にしとかないと、DataMapper の挙動が変わるので注意。
$ merb -i
### エコーバックが on のとき
irb> employees = Employee.all # この時点で SQL が発行されたように見えるが…
~ SELECT `id`, `name`, `department_id` FROM `employees` ORDER BY `id`
=> [#<Employee id=1 name="Kathy" department_id=1>,
#<Employee id=2 name="Mike" department_id=1>,
#<Employee id=3 name="John" department_id=2>,
#<Employee id=4 name="Bill" department_id=3>]
### エコーバックが off のとき
irb> IRB.conf[:MAIN_CONTEXT].echo = false
irb> employees = Employee.all # 実はこの時点では SQL は発行されてなくて、
irb> employees.inspect # inspect のせいで SQL が発行されただけ
~ SELECT `id`, `name`, `department_id` FROM `employees` ORDER BY `id`