Ruby on rails ActiveRecord多重加入?

Ruby on rails ActiveRecord多重加入?,ruby-on-rails,ruby,activerecord,join,Ruby On Rails,Ruby,Activerecord,Join,我正在努力解决活动记录加入问题 我有以下数据库表结构: A - B - C - D - E 及 我想从以下路径之一获取所有记录: A - B - C - D - E A - F - E 我们很满意 我用Active Record尝试了以下方法: A.joins(:B => {:C => {:D => :E}}, :F => :E) .where("some constraints on E and …") 但是,这不起作用,因为所有连接都生成为内部连接,如下所示:

我正在努力解决活动记录加入问题

我有以下数据库表结构:

A - B - C - D - E

我想从以下路径之一获取所有记录:

A - B - C - D - E
A - F - E
我们很满意

我用Active Record尝试了以下方法:

A.joins(:B => {:C => {:D => :E}}, :F => :E)
.where("some constraints on E and …")
但是,这不起作用,因为所有连接都生成为内部连接,如下所示:

SELECT  A.*
FROM A
INNER JOIN B ON A.b_id = B.id
INNER JOIN C ON B.c_id = C.id
INNER JOIN D ON C.d_id = D.id
INNER JOIN E ON D.e_id = E.id
INNER JOIN F ON A.f_id = F.id
INNER JOIN E E_F ON E_F.f_id = F.id
WHERE ("some constraints on E")
我希望我没有在这里输入错误,但核心是,在生成的SQL语句中,两条路径都可以在ON子句中找到

问题是,要从表A返回记录,必须满足两个路径,对吗

我需要一个语句,用于返回两条路径的记录。 最后,它们通过
uniq()
变得独一无二

我还尝试了
merge()
两个单独的选择/连接(路径
A-B-C-D-E”和“A-F-E”),但
merge()
进行交叉。
我提出的唯一解决方案是
+`两个独立的结果集,但问题是我得到一个数组作为结果,因此无法使用(kaminari)分页。 其次,当结果集越来越大时,这不是一个好的解决方案

如果有任何提示,我将不胜感激。
谢谢!

我有一种感觉,您可能会在这里得到一个手工制作的巧妙连接:

SELECT A.*
FROM A
LEFT JOIN (B ON A.b_id = B.id
  INNER JOIN C ON B.c_id = C.id
  INNER JOIN D ON C.d_id = D.id
  INNER JOIN E ON D.e_id = E.id)
LEFT JOIN (F ON A.f_id = F.id
  INNER JOIN E E_F ON E_F.f_id = F.id)
WHERE E_F.id is not null or E.id is not null and
    („some constraints on E“)
当然,最好将其封装在一个范围内

通过F进行连接可能会遇到麻烦,因为它似乎是A和E的父级——如果F有多个E,那么A将返回多行

您可以通过使用相关子查询(半联接)来解决此问题:

请注意,可以从查询中删除F,因为F_ID在A和E中都存在

为了整洁起见,您可以使两个连接都成为半连接

SELECT A.*
FROM A
WHERE (EXISTS (SELECT NULL FROM E E_F WHERE E_F.F.id = A.F_ID) OR
       EXISTS (SELECT NULL FROM B 
               INNER JOIN C ON B.c_id = C.id
               INNER JOIN D ON C.d_id = D.id
               INNER JOIN E ON D.e_id = E.id
               WHERE A.b_id = B.id))
    („some constraints on E“)
把它放到一个范围内

scope :relates_to_e, -> {where("(EXISTS (SELECT NULL
                                            FROM E E_F
                                           WHERE E_F.F.id = A.F_ID) OR
                                  EXISTS (SELECT NULL
                                          FROM B 
                                          INNER JOIN C ON B.c_id = C.id
                                          INNER JOIN D ON C.d_id = D.id
                                          INNER JOIN E ON D.e_id = E.id
                                          WHERE A.b_id = B.id))"}
这并不漂亮,但它将有效地工作,并将不整洁保持在一个范围内

A.relates_to_e.where(„some constraints on E and …“)

非常感谢您的提示!!!我需要的解决方案的核心是EXISTS-或composition。最后,我将作用域定义为带有参数的lambda。(我不想为所有细节打扰您;-)
scope :relates_to_e, -> {where("(EXISTS (SELECT NULL
                                            FROM E E_F
                                           WHERE E_F.F.id = A.F_ID) OR
                                  EXISTS (SELECT NULL
                                          FROM B 
                                          INNER JOIN C ON B.c_id = C.id
                                          INNER JOIN D ON C.d_id = D.id
                                          INNER JOIN E ON D.e_id = E.id
                                          WHERE A.b_id = B.id))"}
A.relates_to_e.where(„some constraints on E and …“)