I have 2 models, User
and UserProfile
. A user
has_one user_profile and a user_profile
belongs_to user.
1) Find without select
This query in console works fine, and take only 2 SQL queries.
>> User.find(:all, :limit => 10, :include => [ :user_profile ])
User Load (0.3ms) SELECT * FROM `users` LIMIT 10
UserProfile Load (0.3ms) SELECT `user_profiles`.* FROM `user_profiles`
WHERE (`user_profiles`.user_id IN (1,2,3,...))
2) Find with select on user
model
I can select columns from User
model, with
>> User.find(:all, :select => '`users`.id, `users`.last_name',
:limit => 10, :include => [ :user_profile ])
User Load (0.3ms) SELECT `users`.id, `users`.last_name FROM `users` LIMIT 10
UserProfile Load (0.2ms) SELECT `user_profiles`.* FROM `user_profiles`
WHERE (`user_profiles`.user_id IN (17510,18087,17508,17288...))
Everything works fine. Note that I must set users.id
in the user selected columns, because the second query doesn't work (return NULL).
3) Find with select on user_profile
model
But when I try to select columns from UserProfile
model, I got only 1 query, which doesn't take care of my :select
>> User.find(:all,
:select => '`users`.id, `users`.last_name, `user_profiles`.permalink',
:limit => 10, :include => [ :user_profile ])
User Load Including Associations (0.6ms) SELECT `users`.`id` AS t0_r0,
`users`.`login` AS t0_r1, ....
`user_profiles`.`id` AS t1_r0,
`user_profiles`.`birth_date` AS t1_r1,
LEFT OUTER JOIN `user_profiles` ON user_profiles.user_id = users.id LIMIT 10
As you can see, the Rails query contains fiels from users and fields from user_profiles that I didn't select.
4) Join method
Codeit purpose a method with join
function :
user_details = User.find(:all,
:select => '`users`.id, `users`.last_name, `user_profiles`.permalink',
:limit => 10, :joins => [ :user_profile ]
)
User Load (0.2ms) SELECT `users`.id, `users`.last_name, `user_profiles`.permalink
FROM `users`
INNER JOIN `user_profiles` ON user_profiles.user_id = users.id
LIMIT 10
This solution works fine with SQL queries, but doesn't make 'link' between User and User Profile. 10 new queries are needed, while the method 1 and 2 make only 2 SQL queries.
user_details.map(&:user_profile).map(&:permalink)
UserProfile Load (0.3ms) SELECT * FROM `user_profiles` WHERE (`user_profiles`.user_id = 1) LIMIT 1
UserProfile Load (0.2ms) SELECT * FROM `user_profiles` WHERE (`user_profiles`.user_id = 2) LIMIT 1
... (10 times) ...
UserProfile Load (0.3ms) SELECT * FROM `user_profiles` WHERE (`user_profiles`.user_id = 10) LIMIT 1
Is there a right syntax to have same results than the 2 first queries, but with a :select
witch select only a few columns of my models ?