ActiveRecord:检查关联是否存在而不加载它?

时间:2016-11-02 20:27:23

标签: activerecord

假设我有User has_one :photo的ActiveRecord模型。在数据库中,photos有一个t.binary列,可能包含大量数据,因此除非我需要,否则我不想SELECT该列。

我想做类似的事情:

users.each do |user|
  image_tag(user_photo_path) if user.photo.present?
end

但是,我不想拨打user.photo.present?,因为:

  • 这样做会加载photo关联,包括SELECT * from photos
  • 即使只能SELECT id FROM photos检查存在,它仍然是N + 1查询。

我真正想要的是使用单个查询加载users,该查询为每个查询提供一个属性,告诉我它是否有关联的照片。

1 个答案:

答案 0 :(得分:1)

使用ActiveRecord 5,这可以:

class User < ActiveRecord::Base                                                                                                                                     
  scope :with_photo_id, -> { 
     left_outer_joins(:photo).select(
       "users.*, photos.id AS photo_id"
     )
   }

 end

然后我可以致电User.with_photo_id并查看user.photo_id.present?

在AR 5之前,加入会更加丑陋:

  joins(
    "LEFT OUTER JOIN photos ON photos.user_id = users.id"
  )