无法使用string链接到left_joins的连接

时间:2017-03-22 20:06:46

标签: ruby-on-rails activerecord left-join ruby-on-rails-5

要点:

通过提醒,我在附件和规则之间存在多对多的关系。 我有一个给定的规则和给定的附件选择(具有给定bug_id的那些)。 我需要浏览所有选定的附件,指出是否有规则警报,使用不同的CSS背景颜色。

外部加入

我使用以下查询得到了正确的结果:

SELECT attachments.*, alerts.rule_id
FROM attachments
     LEFT OUTER JOIN alerts ON alerts.attachment_id = attachments.id
                               and alerts.rule_id = 9
WHERE attachments.bug_id;

我正在寻找类似的东西:

bug.attachments
   .left_joins(alerts: {'rules.id' => 9})
   .select('attachments.*, alerts.rule_id')

数据库

class Alert < ApplicationRecord
  belongs_to :attachment

class Attachment < ApplicationRecord
  has_many :alerts

attachments
|  id   | bug_id |
| 14612 | 38871  |
| 14613 | 38871  |
| 14614 | 38871  |

alerts
| attachment_id | rule_id |
|     14612     |    9    |
|     14614     |    8    |

From子句中的条件

如果没有FROM子句中的alerts.rule_id = 9条件,我们会得到以下结果:

|  id   | rule_id |
| 14612 |    9    |
| 14614 |    8    |
| 14613 |   NULL  |

因此,拥有WHERE子句WHERE alerts.rule_id = 9 or alerts.rule_id is NULL会丢失14612的结果

所以以下内容不起作用:

bug.attachments
   .joins(:alerts)
   .select('attachments.*, alerts.rule_id')
   .where( ??? )

修改

以上是我原始问题的简化和更正版本。 原始问题如下:

警报属于规则和附件,附件属于错误。

class Alert < ApplicationRecord
  belongs_to :attachment
  belongs_to :rule

class Attachment < ApplicationRecord
  belongs_to :bug
  has_many :alerts

class Bug < ApplicationRecord
  has_many :attachments

对于给定的规则,我需要显示给定错误的所有附件,以及是否有警报。我想要以下SQL:

SELECT attachments.*, alerts.id as alert_id
FROM `attachments`
  LEFT OUTER JOIN `alerts` ON `alerts`.`attachment_id` = `attachments`.`id`
  LEFT OUTER JOIN `rules` ON `rules`.`id` = `alerts`.`rule_id` AND rules.id = 9
WHERE `attachments`.`bug_id` = 38871

我可以从这里得到:

bug.attachments
   .joins("LEFT OUTER JOIN `alerts` ON `alerts`.`attachment_id` = `attachments`.`id`")
   .joins("LEFT OUTER JOIN `rules` ON `rules`.`id` = `alerts`.`rule_id` AND rules.id = 9")
   .select('attachments.*, alerts.id as alert_id')
   .map{|attach| [attach.file_name, attach.alert_id]}

我想知道的是如何避免使用字符串SQL片段调用连接。

我正在寻找类似的东西:

bug.attachments
   .left_joins(alerts: {rule: {'rules.id' => 9}})
   .select('attachments.*, alerts.id as alert_id')
   .map{|attach| [attach.file_name, attach.alert_id]}

无论如何都要避免传递SQL字符串吗?

1 个答案:

答案 0 :(得分:0)

实际上我认为你可以通过在where子句中放置rules.id = 9来获得正确的结果。

Consider matrix A of size n by m, and another matrix D of the same size.
Pick starting point S.
Set D[S.y][S.x] to 1.
Add S into a queue Q.
while Q isn't empty:
      get point from top of the queue, call it T, pop the queue
      for all adjacent cells P of T:
              if cell P is visitable:
                     D[P.y][P.x]=D[T.y][T.x]+1
                     push P into queue
The minimum distance from the starting point to any other point P will be found in D[P.y][P.x].
If P can't be reached, then D[p.y][p.x]=0.
To find the actual path, you need to backtrack from the end point to the starting point, by going through the cells of D in a descending order.