It should return one task with 3 users only, this is the same for
to_json. This code works in Rails 2.3.8 (to_xml and to_json returns
one task with 3 users), after updating to Rails 3 beta 4 the to_xml/
to_json methods doesn't work as expected.
So how can I get the xml/json result from an ActiveRecord::Relation
set (with nested includes)?
create_table "users", :force => true do |t|
t.string "name"
end
end
class Project < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to :project
has_and_belongs_to_many :users
end
class User < ActiveRecord::Base
has_and_belongs_to_many :tasks
end
puts Project.includes(:tasks => :users).where('tasks.id is not
null').to_xml(:include => {:tasks => {:include => :users}})
this will return 3 times the same task (task2).
Without the where('tasks.id is not null'), it returns the correct
values. The differnce is in the sql query:
For Project.includes(:tasks => :users) the sql queries are:
SELECT `projects`.* FROM `projects`
SELECT `tasks`.* FROM `tasks` WHERE (`tasks`.project_id IN (1,2))
SELECT `task_users`.* FROM `task_users` WHERE (`task_users`.task_id =
2)
SELECT `users`.* FROM `users` WHERE (`users`.`id` IN (1,2,3))
Project.includes(:tasks => :users).where('tasks.id is not null')
creates a single sql query:
SELECT `projects`.`id` AS t0_r0, `projects`.`name` AS t0_r1,
`projects`.`created_at` AS t0_r2, `projects`.`updated_at` AS t0_r3,
`tasks`.`id` AS t1_r0, `tasks`.`name` AS t1_r1, `tasks`.`project_id`
AS t1_r2, `tasks`.`created_at` AS t1_r3, `tasks`.`updated_at` AS
t1_r4, `users`.`id` AS t2_r0, `users`.`name` AS t2_r1,
`users`.`created_at` AS t2_r2, `users`.`updated_at` AS t2_r3 FROM
`projects` LEFT OUTER JOIN `tasks` ON `tasks`.`project_id` =
`projects`.`id` LEFT OUTER JOIN `task_users` ON `tasks`.`id` =
`task_users`.`task_id` LEFT OUTER JOIN `users` ON `users`.`id` =
`task_users`.`user_id` WHERE (tasks.id is not null)
I think the problem is, that the single sql query returns 3 rows for
task2 (as described in my first post), since Rails edge the to_json/
to_xml return these 3 rows (and each row includes 3 users).