0

我有 2 个模型,User并且UserProfile. 一个userhas_one user_profile 和一个user_profilebelongs_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,...)) 

user2)在模型上使用选择查找

我可以从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)。

user_profile3) 在模型上使用 select 查找

但是当我尝试从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 查询包含来自用户的字段和来自我未选择的 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女巫只选择我的模型的几列?

4

1 回答 1

0

使用join

User.find(:all,
 :select => '`users`.id, `users`.last_name, `user_profiles`.permalink',
 :limit => 10, :joins => [ :user_profile ])

include用于eager loading. 它用于解决(N+1)访问 user_profile 时的查询users问题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)
于 2013-03-18T17:25:55.127 回答