Hi,
I updated my project to Rails 3 (beta 4) and got a problem with
to_json and to_xml.
I have the model structure: Projects has_many Tasks habtm Users
After the line @projects = Project.includes(:tasks
=> :users).where(''tasks.id is not null'')
mysql returns:
| Pr1 | task1 | Peter |
| Pr2 | task2 | Peter |
| Pr2 | task2 | David |
| Pr2 | task2 | Bernd |
| TestProject | task3 | Peter |
| Pr2 | task4 | David |
When I try to get the xml version with:
@projects.to_xml(:include => {:tasks => {:include => :users}})
I get three times the same task for the project Pr2:
<project>
<name>Pr2</name>
<tasks>
<task>
<name>task2</name>
<users>
<user> <name>Peter</name> </user>
<user> <name>David</name> </user>
<user> <name>Bernd</name> </user>
</users>
</task>
<task>
<name>task2</name>
<users>
<user> <name>Peter</name> </user>
<user> <name>David</name> </user>
<user> <name>Bernd</name> </user>
</users>
</task>
<task>
<name>task2</name>
<users>
<user> <name>Peter</name> </user>
<user> <name>David</name> </user>
<user> <name>Bernd</name> </user>
</users>
</task>
</tasks>
</project>
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)?
Thanks for any help!
David
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to
rubyonrails-core+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.
Hi David,
This is what I found with rails edge.
puts Project.find(2).to_xml(:include => {:tasks => {:include
=> :users}})
<project>
<name>pr2</name>
<created-at
type="datetime">2010-06-25T03:50:57Z</created-at>
<updated-at
type="datetime">2010-06-25T03:50:57Z</updated-at>
<id type="integer">2</id>
<tasks type="array">
<task>
<name>task2</name>
<project-id type="integer">2</project-id>
<id type="integer">2</id>
<users type="array">
<user>
<name>Peter</name>
<task-id type="NilClass">2</task-id>
<id type="integer">1</id>
<user-id type="NilClass">1</user-id>
</user>
<user>
<name>David</name>
<task-id type="NilClass">2</task-id>
<id type="integer">2</id>
<user-id type="NilClass">2</user-id>
</user>
<user>
<name>Bernd</name>
<task-id type="NilClass">2</task-id>
<id type="integer">3</id>
<user-id type="NilClass">3</user-id>
</user>
</users>
</task>
</tasks>
</project>
ActiveRecord::Schema.define(:version => 20100625013546) do
create_table "projects", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "tasks", :force => true do |t|
t.string "name"
t.integer "project_id"
end
create_table "tasks_users", :id => false, :force => true do
|t|
t.integer "task_id", :null => false
t.integer "user_id", :null => false
end
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
# seeds.rb
task1 = Task.create!(:name => ''task1'')
task2 = Task.create!(:name => ''task2'')
task3 = Task.create!(:name => ''task3'')
pr1 = Project.create!(:name => ''pr1'')
pr2 = Project.create!(:name => ''pr2'')
task2.project_id = pr2.id
task2.save!
task2.users.create(:name => ''Peter'')
task2.users.create(:name => ''David'')
task2.users.create(:name => ''Bernd'')
On Jun 24, 3:17 pm, David <owns...@gmx.de> wrote:> Hi,
>
> I updated my project to Rails 3 (beta 4) and got a problem with
> to_json and to_xml.
>
> I have the model structure: Projects has_many Tasks habtm Users
>
> After the line @projects = Project.includes(:tasks
> => :users).where(''tasks.id is not null'')
> mysql returns:
>
> | Pr1 | task1 | Peter |
> | Pr2 | task2 | Peter |
> | Pr2 | task2 | David |
> | Pr2 | task2 | Bernd |
> | TestProject | task3 | Peter |
> | Pr2 | task4 | David |
>
> When I try to get the xml version with:
> @projects.to_xml(:include => {:tasks => {:include => :users}})
>
> I get three times the same task for the project Pr2:
>
> <project>
> <name>Pr2</name>
> <tasks>
> <task>
> <name>task2</name>
> <users>
> <user> <name>Peter</name> </user>
> <user> <name>David</name> </user>
> <user> <name>Bernd</name> </user>
> </users>
> </task>
> <task>
> <name>task2</name>
> <users>
> <user> <name>Peter</name> </user>
> <user> <name>David</name> </user>
> <user> <name>Bernd</name> </user>
> </users>
> </task>
> <task>
> <name>task2</name>
> <users>
> <user> <name>Peter</name> </user>
> <user> <name>David</name> </user>
> <user> <name>Bernd</name> </user>
> </users>
> </task>
> </tasks>
> </project>
>
> 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)?
>
> Thanks for any help!
> David
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to
rubyonrails-core+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.
Hi Neeraj,
could you try
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).
On 25 Jun., 05:56, Neeraj Singh <neerajdotn...@gmail.com>
wrote:> Hi David,
>
> This is what I found with rails edge.
>
> puts Project.find(2).to_xml(:include => {:tasks => {:include
> => :users}})
>
> <project>
> <name>pr2</name>
> <created-at
type="datetime">2010-06-25T03:50:57Z</created-at>
> <updated-at
type="datetime">2010-06-25T03:50:57Z</updated-at>
> <id type="integer">2</id>
> <tasks type="array">
> <task>
> <name>task2</name>
> <project-id type="integer">2</project-id>
> <id type="integer">2</id>
> <users type="array">
> <user>
> <name>Peter</name>
> <task-id type="NilClass">2</task-id>
> <id type="integer">1</id>
> <user-id type="NilClass">1</user-id>
> </user>
> <user>
> <name>David</name>
> <task-id type="NilClass">2</task-id>
> <id type="integer">2</id>
> <user-id type="NilClass">2</user-id>
> </user>
> <user>
> <name>Bernd</name>
> <task-id type="NilClass">2</task-id>
> <id type="integer">3</id>
> <user-id type="NilClass">3</user-id>
> </user>
> </users>
> </task>
> </tasks>
> </project>
>
> ActiveRecord::Schema.define(:version => 20100625013546) do
>
> create_table "projects", :force => true do |t|
> t.string "name"
> t.datetime "created_at"
> t.datetime "updated_at"
> end
>
> create_table "tasks", :force => true do |t|
> t.string "name"
> t.integer "project_id"
> end
>
> create_table "tasks_users", :id => false, :force => true
do |t|
> t.integer "task_id", :null => false
> t.integer "user_id", :null => false
> end
>
> 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
>
> # seeds.rb
> task1 = Task.create!(:name => ''task1'')
> task2 = Task.create!(:name => ''task2'')
> task3 = Task.create!(:name => ''task3'')
>
> pr1 = Project.create!(:name => ''pr1'')
> pr2 = Project.create!(:name => ''pr2'')
>
> task2.project_id = pr2.id
> task2.save!
>
> task2.users.create(:name => ''Peter'')
> task2.users.create(:name => ''David'')
> task2.users.create(:name => ''Bernd'')
>
> On Jun 24, 3:17 pm, David <owns...@gmx.de> wrote:
>
>
>
> > Hi,
>
> > I updated my project to Rails 3 (beta 4) and got a problem with
> > to_json and to_xml.
>
> > I have the model structure: Projects has_many Tasks habtm Users
>
> > After the line @projects = Project.includes(:tasks
> > => :users).where(''tasks.id is not null'')
> > mysql returns:
>
> > | Pr1 | task1 | Peter |
> > | Pr2 | task2 | Peter |
> > | Pr2 | task2 | David |
> > | Pr2 | task2 | Bernd |
> > | TestProject | task3 | Peter |
> > | Pr2 | task4 | David |
>
> > When I try to get the xml version with:
> > @projects.to_xml(:include => {:tasks => {:include =>
:users}})
>
> > I get three times the same task for the project Pr2:
>
> > <project>
> > <name>Pr2</name>
> > <tasks>
> > <task>
> > <name>task2</name>
> > <users>
> > <user> <name>Peter</name> </user>
> > <user> <name>David</name> </user>
> > <user> <name>Bernd</name> </user>
> > </users>
> > </task>
> > <task>
> > <name>task2</name>
> > <users>
> > <user> <name>Peter</name> </user>
> > <user> <name>David</name> </user>
> > <user> <name>Bernd</name> </user>
> > </users>
> > </task>
> > <task>
> > <name>task2</name>
> > <users>
> > <user> <name>Peter</name> </user>
> > <user> <name>David</name> </user>
> > <user> <name>Bernd</name> </user>
> > </users>
> > </task>
> > </tasks>
> > </project>
>
> > 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)?
>
> > Thanks for any help!
> > David
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to
rubyonrails-core+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.
I am able to reproduce this problem. Can you open a ticket so that it''s documented. We will have rest of discussion on that ticket. On Jun 25, 5:51 am, David <owns...@gmx.de> wrote:> Hi Neeraj, > > could you try > > 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). > > On 25 Jun., 05:56, Neeraj Singh <neerajdotn...@gmail.com> wrote: > > > > > Hi David, > > > This is what I found with rails edge. > > > puts Project.find(2).to_xml(:include => {:tasks => {:include > > => :users}}) > > > <project> > > <name>pr2</name> > > <created-at type="datetime">2010-06-25T03:50:57Z</created-at> > > <updated-at type="datetime">2010-06-25T03:50:57Z</updated-at> > > <id type="integer">2</id> > > <tasks type="array"> > > <task> > > <name>task2</name> > > <project-id type="integer">2</project-id> > > <id type="integer">2</id> > > <users type="array"> > > <user> > > <name>Peter</name> > > <task-id type="NilClass">2</task-id> > > <id type="integer">1</id> > > <user-id type="NilClass">1</user-id> > > </user> > > <user> > > <name>David</name> > > <task-id type="NilClass">2</task-id> > > <id type="integer">2</id> > > <user-id type="NilClass">2</user-id> > > </user> > > <user> > > <name>Bernd</name> > > <task-id type="NilClass">2</task-id> > > <id type="integer">3</id> > > <user-id type="NilClass">3</user-id> > > </user> > > </users> > > </task> > > </tasks> > > </project> > > > ActiveRecord::Schema.define(:version => 20100625013546) do > > > create_table "projects", :force => true do |t| > > t.string "name" > > t.datetime "created_at" > > t.datetime "updated_at" > > end > > > create_table "tasks", :force => true do |t| > > t.string "name" > > t.integer "project_id" > > end > > > create_table "tasks_users", :id => false, :force => true do |t| > > t.integer "task_id", :null => false > > t.integer "user_id", :null => false > > end > > > 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 > > > # seeds.rb > > task1 = Task.create!(:name => ''task1'') > > task2 = Task.create!(:name => ''task2'') > > task3 = Task.create!(:name => ''task3'') > > > pr1 = Project.create!(:name => ''pr1'') > > pr2 = Project.create!(:name => ''pr2'') > > > task2.project_id = pr2.id > > task2.save! > > > task2.users.create(:name => ''Peter'') > > task2.users.create(:name => ''David'') > > task2.users.create(:name => ''Bernd'') > > > On Jun 24, 3:17 pm, David <owns...@gmx.de> wrote: > > > > Hi, > > > > I updated my project to Rails 3 (beta 4) and got a problem with > > > to_json and to_xml. > > > > I have the model structure: Projects has_many Tasks habtm Users > > > > After the line @projects = Project.includes(:tasks > > > => :users).where(''tasks.id is not null'') > > > mysql returns: > > > > | Pr1 | task1 | Peter | > > > | Pr2 | task2 | Peter | > > > | Pr2 | task2 | David | > > > | Pr2 | task2 | Bernd | > > > | TestProject | task3 | Peter | > > > | Pr2 | task4 | David | > > > > When I try to get the xml version with: > > > @projects.to_xml(:include => {:tasks => {:include => :users}}) > > > > I get three times the same task for the project Pr2: > > > > <project> > > > <name>Pr2</name> > > > <tasks> > > > <task> > > > <name>task2</name> > > > <users> > > > <user> <name>Peter</name> </user> > > > <user> <name>David</name> </user> > > > <user> <name>Bernd</name> </user> > > > </users> > > > </task> > > > <task> > > > <name>task2</name> > > > <users> > > > <user> <name>Peter</name> </user> > > > <user> <name>David</name> </user> > > > <user> <name>Bernd</name> </user> > > > </users> > > > </task> > > > <task> > > > <name>task2</name> > > > <users> > > > <user> <name>Peter</name> </user> > > > <user> <name>David</name> </user> > > > <user> <name>Bernd</name> </user> > > > </users> > > > </task> > > > </tasks> > > > </project> > > > > 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)? > > > > Thanks for any help! > > > David-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Notice that first one works fine but the second one fails.
# works fine
puts Project.includes(:tasks).where(''tasks.id is not
null'').to_xml(:include => {:tasks => {:include => :users}})
# causes duplicates
puts Project.includes(:tasks => :users).where(''tasks.id is not
null'').to_xml(:include => {:tasks => {:include => :users}})
On Jun 25, 5:51 am, David <owns...@gmx.de> wrote:> Hi Neeraj,
>
> could you try
>
> 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).
>
> On 25 Jun., 05:56, Neeraj Singh <neerajdotn...@gmail.com> wrote:
>
>
>
> > Hi David,
>
> > This is what I found with rails edge.
>
> > puts Project.find(2).to_xml(:include => {:tasks => {:include
> > => :users}})
>
> > <project>
> > <name>pr2</name>
> > <created-at
type="datetime">2010-06-25T03:50:57Z</created-at>
> > <updated-at
type="datetime">2010-06-25T03:50:57Z</updated-at>
> > <id type="integer">2</id>
> > <tasks type="array">
> > <task>
> > <name>task2</name>
> > <project-id type="integer">2</project-id>
> > <id type="integer">2</id>
> > <users type="array">
> > <user>
> > <name>Peter</name>
> > <task-id type="NilClass">2</task-id>
> > <id type="integer">1</id>
> > <user-id type="NilClass">1</user-id>
> > </user>
> > <user>
> > <name>David</name>
> > <task-id type="NilClass">2</task-id>
> > <id type="integer">2</id>
> > <user-id type="NilClass">2</user-id>
> > </user>
> > <user>
> > <name>Bernd</name>
> > <task-id type="NilClass">2</task-id>
> > <id type="integer">3</id>
> > <user-id type="NilClass">3</user-id>
> > </user>
> > </users>
> > </task>
> > </tasks>
> > </project>
>
> > ActiveRecord::Schema.define(:version => 20100625013546) do
>
> > create_table "projects", :force => true do |t|
> > t.string "name"
> > t.datetime "created_at"
> > t.datetime "updated_at"
> > end
>
> > create_table "tasks", :force => true do |t|
> > t.string "name"
> > t.integer "project_id"
> > end
>
> > create_table "tasks_users", :id => false, :force =>
true do |t|
> > t.integer "task_id", :null => false
> > t.integer "user_id", :null => false
> > end
>
> > 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
>
> > # seeds.rb
> > task1 = Task.create!(:name => ''task1'')
> > task2 = Task.create!(:name => ''task2'')
> > task3 = Task.create!(:name => ''task3'')
>
> > pr1 = Project.create!(:name => ''pr1'')
> > pr2 = Project.create!(:name => ''pr2'')
>
> > task2.project_id = pr2.id
> > task2.save!
>
> > task2.users.create(:name => ''Peter'')
> > task2.users.create(:name => ''David'')
> > task2.users.create(:name => ''Bernd'')
>
> > On Jun 24, 3:17 pm, David <owns...@gmx.de> wrote:
>
> > > Hi,
>
> > > I updated my project to Rails 3 (beta 4) and got a problem with
> > > to_json and to_xml.
>
> > > I have the model structure: Projects has_many Tasks habtm Users
>
> > > After the line @projects = Project.includes(:tasks
> > > => :users).where(''tasks.id is not null'')
> > > mysql returns:
>
> > > | Pr1 | task1 | Peter |
> > > | Pr2 | task2 | Peter |
> > > | Pr2 | task2 | David |
> > > | Pr2 | task2 | Bernd |
> > > | TestProject | task3 | Peter |
> > > | Pr2 | task4 | David |
>
> > > When I try to get the xml version with:
> > > @projects.to_xml(:include => {:tasks => {:include =>
:users}})
>
> > > I get three times the same task for the project Pr2:
>
> > > <project>
> > > <name>Pr2</name>
> > > <tasks>
> > > <task>
> > > <name>task2</name>
> > > <users>
> > > <user> <name>Peter</name>
</user>
> > > <user> <name>David</name>
</user>
> > > <user> <name>Bernd</name>
</user>
> > > </users>
> > > </task>
> > > <task>
> > > <name>task2</name>
> > > <users>
> > > <user> <name>Peter</name>
</user>
> > > <user> <name>David</name>
</user>
> > > <user> <name>Bernd</name>
</user>
> > > </users>
> > > </task>
> > > <task>
> > > <name>task2</name>
> > > <users>
> > > <user> <name>Peter</name>
</user>
> > > <user> <name>David</name>
</user>
> > > <user> <name>Bernd</name>
</user>
> > > </users>
> > > </task>
> > > </tasks>
> > > </project>
>
> > > 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)?
>
> > > Thanks for any help!
> > > David
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to
rubyonrails-core+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.
Ticket: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4971-nested-includes-in-ar-causes-duplicates-in-to_json-to_xml On 25 Jun., 15:51, Neeraj Singh <neeraj....@gmail.com> wrote:> Notice that first one works fine but the second one fails. > > # works fine > puts Project.includes(:tasks).where(''tasks.id is not > null'').to_xml(:include => {:tasks => {:include => :users}}) > > # causes duplicates > puts Project.includes(:tasks => :users).where(''tasks.id is not > null'').to_xml(:include => {:tasks => {:include => :users}}) > > On Jun 25, 5:51 am, David <owns...@gmx.de> wrote: > > > > > Hi Neeraj, > > > could you try > > > 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). > > > On 25 Jun., 05:56, Neeraj Singh <neerajdotn...@gmail.com> wrote: > > > > Hi David, > > > > This is what I found with rails edge. > > > > puts Project.find(2).to_xml(:include => {:tasks => {:include > > > => :users}}) > > > > <project> > > > <name>pr2</name> > > > <created-at type="datetime">2010-06-25T03:50:57Z</created-at> > > > <updated-at type="datetime">2010-06-25T03:50:57Z</updated-at> > > > <id type="integer">2</id> > > > <tasks type="array"> > > > <task> > > > <name>task2</name> > > > <project-id type="integer">2</project-id> > > > <id type="integer">2</id> > > > <users type="array"> > > > <user> > > > <name>Peter</name> > > > <task-id type="NilClass">2</task-id> > > > <id type="integer">1</id> > > > <user-id type="NilClass">1</user-id> > > > </user> > > > <user> > > > <name>David</name> > > > <task-id type="NilClass">2</task-id> > > > <id type="integer">2</id> > > > <user-id type="NilClass">2</user-id> > > > </user> > > > <user> > > > <name>Bernd</name> > > > <task-id type="NilClass">2</task-id> > > > <id type="integer">3</id> > > > <user-id type="NilClass">3</user-id> > > > </user> > > > </users> > > > </task> > > > </tasks> > > > </project> > > > > ActiveRecord::Schema.define(:version => 20100625013546) do > > > > create_table "projects", :force => true do |t| > > > t.string "name" > > > t.datetime "created_at" > > > t.datetime "updated_at" > > > end > > > > create_table "tasks", :force => true do |t| > > > t.string "name" > > > t.integer "project_id" > > > end > > > > create_table "tasks_users", :id => false, :force => true do |t| > > > t.integer "task_id", :null => false > > > t.integer "user_id", :null => false > > > end > > > > 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 > > > > # seeds.rb > > > task1 = Task.create!(:name => ''task1'') > > > task2 = Task.create!(:name => ''task2'') > > > task3 = Task.create!(:name => ''task3'') > > > > pr1 = Project.create!(:name => ''pr1'') > > > pr2 = Project.create!(:name => ''pr2'') > > > > task2.project_id = pr2.id > > > task2.save! > > > > task2.users.create(:name => ''Peter'') > > > task2.users.create(:name => ''David'') > > > task2.users.create(:name => ''Bernd'') > > > > On Jun 24, 3:17 pm, David <owns...@gmx.de> wrote: > > > > > Hi, > > > > > I updated my project to Rails 3 (beta 4) and got a problem with > > > > to_json and to_xml. > > > > > I have the model structure: Projects has_many Tasks habtm Users > > > > > After the line @projects = Project.includes(:tasks > > > > => :users).where(''tasks.id is not null'') > > > > mysql returns: > > > > > | Pr1 | task1 | Peter | > > > > | Pr2 | task2 | Peter | > > > > | Pr2 | task2 | David | > > > > | Pr2 | task2 | Bernd | > > > > | TestProject | task3 | Peter | > > > > | Pr2 | task4 | David | > > > > > When I try to get the xml version with: > > > > @projects.to_xml(:include => {:tasks => {:include => :users}}) > > > > > I get three times the same task for the project Pr2: > > > > > <project> > > > > <name>Pr2</name> > > > > <tasks> > > > > <task> > > > > <name>task2</name> > > > > <users> > > > > <user> <name>Peter</name> </user> > > > > <user> <name>David</name> </user> > > > > <user> <name>Bernd</name> </user> > > > > </users> > > > > </task> > > > > <task> > > > > <name>task2</name> > > > > <users> > > > > <user> <name>Peter</name> </user> > > > > <user> <name>David</name> </user> > > > > <user> <name>Bernd</name> </user> > > > > </users> > > > > </task> > > > > <task> > > > > <name>task2</name> > > > > <users> > > > > <user> <name>Peter</name> </user> > > > > <user> <name>David</name> </user> > > > > <user> <name>Bernd</name> </user> > > > > </users> > > > > </task> > > > > </tasks> > > > > </project> > > > > > 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)? > > > > > Thanks for any help! > > > > David-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.