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>]