【问题标题】:Selecting different condition based on presence of association?根据关联的存在选择不同的条件?
【发布时间】:2012-04-05 09:24:12
【问题描述】:

我的折扣模型有一个期间关联。我正在尝试编写一个选择从今天开始的折扣的范围,其中包括:

  1. 如果有句点,请选择从今天开始的那些句点。
  2. 如果没有期间,则选择昨天和今天之间创建的折扣

我当前的查询可以做到第一个要求(实际上比这个复杂一点):

def self.begins_today
  joins(:event).where("begin = ?", today)
end

但是我怎样才能达到要求 2?

我正在考虑使用 SQL UNION 命令,但我认为它不能用作范围。

【问题讨论】:

    标签: sql ruby-on-rails ruby-on-rails-3 activerecord union


    【解决方案1】:

    我假设事件包含期间关联?

    在任何情况下,您都希望在 discounts 表和 period 表之间进行左连接。这将为您提供执行begin = today where 子句的期间数据,如果没有期间,则为 null。因此选择数据的 SQL 将是

    SELECT [columns]
    FROM discounts_table
    LEFT JOIN periods_table ON periods_table.discount_id = discounts_table.id
    WHERE (periods_table.begin = [today]) OR (periods_table.begin IS NULL AND discounts_table.created_at BETWEEN [yesterday] AND [today])
    

    在 Rails 中,您应该能够按如下方式实现:

    Discount
      .joins("LEFT JOIN periods_table ON periods_table.discount_id = discounts_table.id")
      .where("(periods_table.begin = ?) OR (periods_table.begin IS NULL AND discounts_table.created_at BETWEEN ? AND ?)", today, today, 1.day.ago.to_date)
    

    不幸的是,您需要使用 SQL 语句,而不是让 rails 为您创建它:

    1. 使用符号连接只会创建 INNER JOIN,而不是 LEFT JOIN
    2. 符号、哈希等将使用 AND 而不是 OR 组合条件

    【讨论】:

    • 谢谢,它有效。我注意到的一件事是它很慢(4000 个折扣/8000 个周期,都带有索引)。我想一旦我混合其他范围就可以了。
    猜你喜欢
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 2014-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    相关资源
    最近更新 更多