我有2个模型,User
和UserProfile
。 user
has_one user_profile和user_profile
belongs_to用户。
1)不选择
查找控制台中的此查询工作正常,只需要2个SQL查询。
>> 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)使用user
型号
我可以使用
从User
模型中选择列
>> 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...))
一切正常。请注意,我必须在用户选择的列中设置users.id
,因为第二个查询不起作用(返回NULL)。
3)使用user_profile
型号
但是当我尝试从UserProfile
模型中选择列时,我只获得了1个查询,但没有关注我的: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
如您所见,Rails查询包含来自用户的fiels和来自user_profiles的字段,我没有选择。
4)加入方法
Codeit用于join
函数的方法:
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
此解决方案适用于SQL查询,但不会在用户和用户配置文件之间建立“链接”。需要10个新查询,而方法1和2只需要2个SQL查询。
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
是否有正确的语法可以获得与2个第一个查询相同的结果,但使用:select
女巫只选择我的模型中的几列?
答案 0 :(得分:0)
使用join
:
User.find(:all,
:select => '`users`.id, `users`.last_name, `user_profiles`.permalink',
:limit => 10, :joins => [ :user_profile ])
include
用于eager loading
。当您使用(N+1)
users
时,它用于解决user_profile
查询问题,以便访问user_profile。如果要选择包含的表格columns
,则需要使用join
。如果使用包含表的列,则会忽略select
子句。
修改强>
user_details = User.find(:all,
:select => '`users`.id, `users`.last_name, `user_profiles`.permalink',
:limit => 10, :joins => [ :user_profile ]
)
user_details.map(&:permalink)