简体   繁体   English

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

[英]How can I do a LEFT OUTER JOIN using Rails ActiveRecord?

I don't have any ideas. 我没有任何想法。 Could you give me any clues (like reference sites). 你能给我任何线索(比如参考站点)。 Any help will be appreciated. 任何帮助将不胜感激。

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

Expected SQL statement: 预期的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

I tried to set up associations below but I dont know what to do after this. 我尝试在下面建立协会,但我不知道在此之后该怎么办。

class Group < ActiveRecord::Base
  has_many :user_group_cmb
end

class UserGroupCmb < ActiveRecord::Base
  has_many :group
end

Rails Version: 3.1.1 Rails版本:3.1.1

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

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

Rails 5+ allows you to do the following: Rails 5+允许您执行以下操作:

Group.left_outer_joins(:user_group_cmb)

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

You can do this in rails 3.x regardless if you are referencing the table or not in a where clause: 您可以在rails 3.x中执行此操作,无论您是否在where子句中引用该表:

Group.eager_load(:user_group_cmb)

...and it will perform a left outter join ......它将执行左外连接

It might be quite important to mention that using includes has possibly unwanted side-effects. 提及使用包含可能有不良副作用可能是非常重要的。

if the filtered association is subsequently scoped, all of the original filtering disappears 如果过滤后的关联随后作用域,则所有原始过滤消失

As it turns out, by scoping on the filtered association we've lost any filtering-as-side-effect that we attained from includes. 事实证明,通过对过滤后的关联进行确定,我们已经失去了从包含中获得的任何过滤副作用。 And it's not because of how we searched, either. 而且这也不是因为我们如何搜索。

Make sure to read the complete article and alternatively there's a gem for that . 一定要阅读完整的文章,或者有一个宝石

Use a custom joins statement: 使用自定义连接语句:

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

The problem with the accepted answer is that it will actually do a LEFT INNER JOIN technically because it won't display entries where the user_group_cmbs. user_id 接受的答案的问题是它实际上会在技术上执行LEFT INNER JOIN因为它不会显示user_group_cmbs. user_id条目user_group_cmbs. user_id user_group_cmbs. user_id is null (which would be the reason to do a LEFT OUTER JOIN ). user_group_cmbs. user_id为null(这是执行LEFT OUTER JOIN的原因)。

A working solution is to use #references : 一个有效的解决方案是使用#references

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

Or the even more convenient #eager_load : 或者更方便的#eager_load

Group.eager_load(:user_group_cmb)

Read the more detailed explanation here . 请在此处阅读更详细的说明。

Use has_and_belongs_to_many if you just need to link users to groups. 如果您只需要将用户链接到组,请使用has_and_belongs_to_many Use has_many :through if you need to store additional membership information. 如果您需要存储其他成员资格信息,请使用has_many:through

Example: 例:

class User < ActiveRecord::Base
  has_and_belongs_to_many :groups
end

class Group < ActiveRecord::Base
  has_and_belongs_to_many :users      
end

Couldn't comment to an earlier answer because well I don't have 50 reputation. 无法对之前的答案发表评论,因为我没有50的声誉。 But here's how it worked for me when I ran into below error 但是当我遇到下面的错误时,这是​​我的工作方式

includes-referenced relation raises a StatementInvalid exception, complaining it misses a FROM-clause entry. 包含引用的关系引发一个StatementInvalid异常,抱怨它错过了一个FROM子句条目。 I need to add an explicit call to join, which defaults to being inner. 我需要添加一个显式调用join,默认为inner。

I had to use .references and mention the table name or for it get added to the FROM-clause 我不得不使用.references并提及表名,或者将其添加到FROM子句中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM