Rails includes association with condition in left join

跟風遠走 提交于 2019-12-24 02:38:29

问题


Can I add some condition to the LEFT JOIN sql that Rails generate for the includes method? (Rails 4.2.1, postresql).

I need to get all(!) the users with preloading ( not N+1 when I will puts in a view count of comments, posts and etc) of associations, but associations need to be filtered by some conditions.

Example:

User.includes(:comments) 
# => SELECT * FROM users LEFT JOIN comments ON ...

This will return all the users and preload comments if they exists. If I will add some conditions for the "comments" association in where, then SQL doesn't return ALL the users, for example:

User.includes(:comments).where(comments: {published_at: Date.today})
# => SELECT * FROM users LEFT JOIN comments ON ... WHERE comments.published_at = ...

This will return only users, that have comments, published today.

I need to put conditions inside LEFT JOIN AND save preloading (load objects to the memory - simple left join with joins method doesn't preload associations).

SELECT * FROM users LEFT JOIN comments ON (... AND comments.published_at = ...)

Those SQL will return right what I need (all the users, and their comments, published in requested date, if they exists)! But ... I cant generate it with the Rails includes method, and `joins' doesn't preload associations.

What do you advice me? Thanks!


回答1:


Rails doesn't have methods in the framework library to do what you want. This might work, though

class User < ActiveRecord::Base
  has_many :comments
  has_many :recent_comments, -> { where(published_at: Date.today) }, class_name: "Comment"
end

Then query for Users and preload recent_comments

@users = User.preload(:recent_comments)


来源:https://stackoverflow.com/questions/29687535/rails-includes-association-with-condition-in-left-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!