【发布时间】:2018-09-14 19:40:07
【问题描述】:
首先让我承认有几种不同的方法可以实现重叠,但关于这个问题,我特别想弄清楚如何将实际的PostgreSQL OVERLAPS 方法与Arel 一起使用。为此,这个问题更多地与更好地理解 Arel 有关,而不是实现某些版本的重叠功能。
我正在使用Rails 5.1
这是我试图在 Arel 中复制的 SQL 语句:
SELECT DISTINCT
venues.id
FROM
venues
LEFT OUTER JOIN
reservations
ON
venues.id = reservations.venue_id
WHERE (
(reservations.venue_id IS NULL)
OR NOT (
(reservations.start, reservations.end)
OVERLAPS
(DATE '2018-09-02', DATE '2018-09-03')
)
)
我目前有以下确实会生成上述内容:
Venue.arel_table.project(
Venue.arel_table[:id]
).from(
Venue.arel_table
).join(
Reservation.arel_table, Arel::Nodes::OuterJoin
).on(
Venue.arel_table[:id].eq(Reservation.arel_table[:venue_id])
).where(
Arel::Nodes::Grouping.new(
Reservation.arel_table[:venue_id].eq(nil)
).or(
Arel.sql("NOT ((reservations.start, reservations.end) OVERLAPS (DATE '2018-09-02', DATE '2018-09-03'))")
)
)
但是,我觉得可能有更好的方法来做到这一点;我一直在尝试为OVERLAPS 实现Arel::Nodes::NamedFunction,但是,当我将上面的Arel.sql 语句替换为以下语句时,它无法正确执行SQL:
Arel::Nodes::NamedFunction.new(
'OVERLAPS',
[
Arel::Nodes::SqlLiteral.new('(reservations.start, reservations.end)'),
Arel::Nodes::SqlLiteral.new("(DATE '2018-09-02', DATE '2018-09-03')")
]
)
结果
...OVERLAPS ((reservations.start, reservations.end), (DATE '2018-09-02', DATE '2018-09-03'))
用Arel 实现OVERLAPS 的正确方法是什么?
【问题讨论】:
标签: ruby-on-rails postgresql arel