DataMapper で relation を使った検索
ドキュメントに載ってないことを補足していこうシリーズ。
DataMapper で、たとえば次のようなモデルクラスがあるとする。
### 従業員 class Employee include DataMapper::Resource property :id, Serial property :name, String, :nullable => false property :department_id, Integer belongs_to :department end ### 部門 class Department include DataMapper::Resource property :id, Serial property :name, String, :nullabel => false, :unique_index => true has n, :employees end
ここで、従業員の名前で検索するには次のようにする (これはよく知られている)。
- 「Employee.all(:name => "Kathy")」とすると、名前が Kathy である従業員
- 「Employee.all(:name.not => "Kathy")」とすると、名前が Kathy でない従業員
また relation を使った検索は、次のようにする (これはドキュメントに載ってないと思う)。
- 「Employee.all("department.name" => "Sales")」とすると、所属部門の名前が Sales である従業員
- 「Employee.all("department.name.not" => "Sales")」とすると、所属部門の名前が Sales でない従業員
実行例:
$ merb -i irb> Employee.all("department.name"=>"Sales") ~ SELECT "employees"."id", "employees"."name", "employees"."department_id" FROM "employees" INNER JOIN "departments" ON ("departments"."id" = "employees"."department_id") WHERE ("departments"."name" = 'Sales') ORDER BY "employees"."id" => [#<Employee id=3 name="Kathy" department_id=1>] irb> Employee.all("department.name.not"=>"Sales") ~ SELECT "employees"."id", "employees"."name", "employees"."department_id" FROM "employees" INNER JOIN "departments" ON ("departments"."id" = "employees"."department_id") WHERE ("departments"."name" <> 'Sales') ORDER BY "employees"."id" => [#<Employee id=4 name="Jack" department_id=2>, #<Employee id=5 name="Bill" department_id=2>, #<Employee id=6 name="Scott" department_id=3>]
Merb のバージョンを更新すると起動しない場合
Merb を新しいバージョンにして起動すると、次のようなエラーがでる場合がある。
~ FATAL: The gem merb-action-args (= 1.0.2, runtime), [] was not found
この場合は、config/dependencies.rb に書かれてあるバージョンを書き換えてやるとよい。
merb_gems_version = "1.0.4" dm_gems_version = "0.9.8"
「FATAL: Could not bind to 4000」と言われて Merb が起動できない場合
症状:「FATAL: Could not bind to 4000」と言われて、Merb が起動できない。
原因:すでに別の Merb が起動しているか、前に起動したときの worker process が終了されていない。
対処:4000 番ポートを使っている process を lsof で見つけ、kill する。
$ merb merb : worker (port 4000) ~ Starting Mongrel at port 4000 merb : worker (port 4000) ~ merb : worker (port 4000) ~ FATAL: Could not bind to 4000. It was already in use merb : worker (port 4000) ~ $ sudo lsof -i:4000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ruby 52132 kwatch 13u IPv4 0xbe26a68 0t0 TCP *:terabase (LISTEN) $ kill -9 52132