如何使用Rails ActiveRecord进行LEFT OUTER JOIN?

我没有任何想法。 你能给我任何线索(比如参考站点)。 任何帮助将不胜感激。

Model1: GROUP(id, name) Model2: USER_GROUP_CMB(id, user_id, group_id) 

预期的SQL语句:

 SELECT * FROM groups AS g LEFT OUTER JOIN user_group_cmbs AS cmb ON g.id = cmb.group_id WHERE cmb.user_id = 1 

我尝试在下面建立协会,但我不知道在此之后该怎么办。

 class Group < ActiveRecord::Base has_many :user_group_cmb end class UserGroupCmb < ActiveRecord::Base has_many :group end 

Rails版本:3.1.1

我相信如果您对includes关联使用的表执行条件,则includes将使用LEFT OUTER JOIN查询:

 Group.includes(:user_group_cmb).where(user_group_cmbs: { user_id: 1 }) 

Rails 5+允许您执行以下操作:

 Group.left_outer_joins(:user_group_cmb) 

http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-left_joins

您可以在rails 3.x中执行此操作,无论您是否在where子句中引用该表:

 Group.eager_load(:user_group_cmb) 

……它将执行左外连接

提及使用包含可能具有不良副作用可能是非常重要的。

如果过滤后的关联随后作用域,则所有原始过滤消失

事实certificate,通过对过滤后的关联进行确定,我们已经失去了从包含中获得的任何过滤副作用。 而且这也不是因为我们如何搜索。

一定要阅读完整的文章,或者有一个gem 。

使用自定义连接语句:

 Group.joins("left outer join user_group_cmbs as cmb on groups.id = cmb.group_id") .where("cmb.user_id = ?", 1) 

接受的答案的问题是它实际上会在技术上执行LEFT INNER JOIN因为它不会显示user_group_cmbs. user_id条目user_group_cmbs. user_id user_group_cmbs. user_id为null(这是进行LEFT OUTER JOIN的原因)。

一个有效的解决方案是使用#references

 Group.includes(:user_group_cmb).references(:user_group_cmb) 

或者更方便的#eager_load

 Group.eager_load(:user_group_cmb) 

请在此处阅读更详细的说明。

如果您只需要将用户链接到组,请使用has_and_belongs_to_many 。 如果您需要存储其他成员资格信息,请使用has_many:through 。

例:

 class User < ActiveRecord::Base has_and_belongs_to_many :groups end class Group < ActiveRecord::Base has_and_belongs_to_many :users end 

无法对之前的答案发表评论,因为我没有50的声誉。 但是当我遇到下面的错误时,这是​​我的工作方式

包含引用的关系引发一个StatementInvalidexception,抱怨它错过了一个FROM子句条目。 我需要添加一个显式调用join,默认为inner。

我不得不使用.references并提及表名,或者将其添加到FROM子句中