This project is archived and is in readonly mode.
Mixing joins and include conflicts
Reported by Elías Orozco | October 15th, 2008 @ 11:31 PM | in 2.x
I have found that Rails doesn't works well when mixing joins and includes. For example I have the following models: Event, Attendance and User.
class Event < ActiveRecord::Base
# User that creates the event
belongs_to :created_by,
:select => "id, name, lastname",
:foreign_key => "user_id",
:class_name => "User"
has_many :attendances
has_many :users, :through => :attendances
############################################
class Attendance < ActiveRecord::Base
belongs_to :event
belongs_to :user
############################################
class User < ActiveRecord::Base
has_many :attendances
has_many :events, :through => :attendances
The events table has a boolean attribute called private (1 if event is private, 0 instead). So basically let's imagine we want to fetch all the events I can attend, that is, all the events that are public and those that are private and I've been invited.
The query should be like this:
Event.find(:all,
:include => [:created_by],
:joins => "LEFT OUTER JOIN attendances ON
attendances.event_id = events.id",
:conditions => ["((events.private = 0) OR
(events.private = 1 AND
attendances.user_id = ?))",
current_user],
:order => "events.start_date DESC")
From this query I should expect something like this on my development log.
SELECT events.*
FROM events
LEFT OUTER JOIN attendances ON attendances.event_id = events.id
WHERE ((events.private = 0) OR
(events.private = 1 AND
attendances.user_id = 1))
ORDER BY events.start_date DESC
SELECT id, name, lastname FROM users WHERE id IN (3,4,7)
But this is what really happens. Here's the real query generated by rails on my development log.
SELECT `events`.`id` AS t0_r0, `events`.`start_date` AS t0_r1, `events`.`title` AS t0_r2, `events`.`place` AS t0_r3, `events`.`description` AS t0_r4, `events`.`user_id` AS t0_r5, `events`.`event_category_id` AS t0_r6, `events`.`created_at` AS t0_r7, `events`.`updated_at` AS t0_r8, `events`.`neighborhood_id` AS t0_r9, `events`.`end_date` AS t0_r10, `events`.`private` AS t0_r11, `users`.`id` AS t1_r0, `users`.`email` AS t1_r1, `users`.`crypted_password` AS t1_r2, `users`.`salt` AS t1_r3, `users`.`name` AS t1_r4, `users`.`lastname` AS t1_r5, `users`.`gender` AS t1_r6, `users`.`zipcode` AS t1_r7, `users`.`birthday` AS t1_r8, `users`.`remember_token` AS t1_r9, `users`.`remember_token_expires_at` AS t1_r10, `users`.`activation_code` AS t1_r11, `users`.`activated_at` AS t1_r12, `users`.`created_at` AS t1_r13, `users`.`updated_at` AS t1_r14, `users`.`photo_file_name` AS t1_r15, `users`.`photo_content_type` AS t1_r16, `users`.`photo_file_size` AS t1_r17, `users`.`status_message` AS t1_r18, `users`.`status_update` AS t1_r19, `users`.`state` AS t1_r20 FROM `events` LEFT OUTER JOIN `users` ON `users`.id = `events`.user_id LEFT OUTER JOIN attendances ON attendances.event_id = events.id WHERE (((events.private = 0) OR (events.private = 1 AND attendances.user_id = 1))) ORDER BY events.start_date DESC
As you can see the query sort of works, but not in the way it should. A lot of alias are created and more columns are selected than the ones I specify. So well, here I leave it and hope someone has noticed this too so we can work on it.
Comments and changes to this ticket
-
Frederick Cheung December 18th, 2008 @ 11:32 AM
- State changed from new to duplicate
Duplicate of #528
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>