DataMapper での 1+N 問題

DataMapper では、いわゆる 1+N 問題は起こらないと言われている。

たとえば次のような例。ActiveRecord なら 1+N コの SELECT 文が発行されるけど、DataMapper では 1+1 コの SELECT 文だけを発行する。

$ merb -i
irb> IRB.conf[:MAIN_CONTEXT].echo = false   # エコーバックを切る
irb> employees = Employee.all
irb> employees.each {|emp| p emp.department }   # 1+1 コの SQL 文
 ~ SELECT `id`, `name`, `department_id` FROM `employees` ORDER BY `id`
 ~ 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">


これは belongs_to の場合だけど、has n の場合も同じように 1+N を避けて 1+1 に動作する。

$ merb -i
irb> IRB.conf[:MAIN_CONTEXT].echo = false   # エコーバックを切る
irb> departments = Department.all
irb> departments.each {|dept| p dept.employees }   # 1+1 コの SQL 文
 ~ SELECT `id`, `name` FROM `departments` ORDER BY `id`
 ~ SELECT `id`, `name`, `department_id` FROM `employees` WHERE (`department_id` IN (1, 3, 2)) 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>]


ただ、many to many にはうまくいかなくて、1+N コの SQL が発行されてしまう。

irb> authors = Author.all
irb> authors.each {|author| p author.books }
>> authors.each {|author| p author.books }
 ~ SELECT `id`, `name` FROM `authors` ORDER BY `id`   # 1+N コの SQL 文
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 1) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=1 title="Merb in Action">]
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 2) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=1 title="Merb in Action">]
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 3) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=1 title="Merb in Action">]
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 4) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=2 title="Beginning Merb">]
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 5) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=2 title="Beginning Merb">]


現在の DataMapper では、これが限界。一応ここの改善も ToDo リストには入っているらしんだけど、対応されるのはずいぶん先になりそう。

問題は、これの回避策がないってことなんだよな。Author#books= とか Book#authors= とかが使えればいいんだけど、少なくとも DataMapper 0.9.8 では使えない。

irb> book1.authors = [author1, author2]
DataMapper::Associations::ImmutableAssociationError: You can not modify this association
        from /usr/local/lib/ruby/gems/1.8/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb:255:in `assert_mutable'
        from /usr/local/lib/ruby/gems/1.8/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb:117:in `replace'
        from /usr/local/lib/ruby/gems/1.8/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb:21:in `authors='
        from (irb):32
        from :0


Many to many での、いい解決方法があれば教えてください。