简体   繁体   English

LEFT OUTER加入Rails 3

[英]LEFT OUTER joins in Rails 3

I have the following code: 我有以下代码:

@posts = Post.joins(:user).joins(:blog).select

which is meant to find all posts and return them and the associated users and blogs. 这是为了查找所有帖子并返回它们以及相关的用户和博客。 However, users are optional which means that the INNER JOIN that :joins generates is not returning lots of records. 但是,用户是可选的,这意味着:joins生成的INNER JOIN不会返回大量记录。

How do I use this to generate a LEFT OUTER JOIN instead? 如何使用它来生成LEFT OUTER JOIN呢?

@posts = Post.joins("LEFT OUTER JOIN users ON users.id = posts.user_id").
              joins(:blog).select

You can do with this with includes as documented in the Rails guide : 您可以使用Rails指南中记录的 includes来执行此操作:

Post.includes(:comments).where(comments: {visible: true})

Results in: 结果是:

SELECT "posts"."id" AS t0_r0, ...
       "comments"."updated_at" AS t1_r5
FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"
WHERE (comments.visible = 1)

I'm a big fan of the squeel gem : 我是squeel gem的忠实粉丝:

Post.joins{user.outer}.joins{blog}

It supports both inner and outer joins, as well as the ability to specify a class/type for polymorphic belongs_to relationships. 它支持innerouter联接,以及为多态belongs_to关系指定类/类型的功能。

使用eager_load

@posts = Post.eager_load(:user)

By default when you pass ActiveRecord::Base#joins a named association, it will perform an INNER JOIN. 默认情况下,当您传递ActiveRecord::Base#joins一个命名关联时,它将执行INNER JOIN。 You'll have to pass a string representing your LEFT OUTER JOIN. 你必须传递一个表示你的LEFT OUTER JOIN的字符串。

From the documentation : 文档

:joins - Either an SQL fragment for additional joins like " LEFT JOIN comments ON comments.post_id = id " (rarely needed), named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s), or an array containing a mixture of both strings and named associations. :joins - 用于其他连接的SQL片段,如“ LEFT JOIN comments ON comments.post_id = id ”(很少需要),用于:include选项的相同形式的命名关联,它将在关联的表上执行INNER JOIN (s),或包含字符串和命名关联的混合的数组。

If the value is a string, then the records will be returned read-only since they will have attributes that do not correspond to the table's columns. 如果值是字符串,则记录将以只读方式返回,因为它们将具有与表的列不对应的属性。 Pass :readonly => false to override. 通过:readonly => false覆盖。

There is a left_outer_joins method in activerecord. activerecord中有一个left_outer_joins方法。 You can use it like this: 你可以像这样使用它:

@posts = Post.left_outer_joins(:user).joins(:blog).select

Good news, Rails 5 now supports LEFT OUTER JOIN . 好消息,Rails 5现在支持LEFT OUTER JOIN Your query would now look like: 您的查询现在看起来像:

@posts = Post.left_outer_joins(:user, :blog)
class User < ActiveRecord::Base
     has_many :friends, :foreign_key=>"u_from",:class_name=>"Friend"
end

class Friend < ActiveRecord::Base
     belongs_to :user
end


friends = user.friends.where(:u_req_status=>2).joins("LEFT OUTER JOIN users ON users.u_id = friends.u_to").select("friend_id,u_from,u_to,u_first_name,u_last_name,u_email,u_fbid,u_twtid,u_picture_url,u_quote")

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

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