【问题标题】:Ruby on Rails Find Where No RecordRuby on Rails 查找没有记录的地方
【发布时间】:2011-08-13 16:21:20
【问题描述】:

我有以下关联:

Outlet => has_many :checkins
Checkin => belongs_to :outlet

每天,Outlet 需要进行 1 次签到。 我可以通过以下方式获取今天签到的网点列表:

Checkin.where('DATE(created_at) = ?', Date.Today)

但是,我不确定如何获得今天没有与他们关联的签到的网点列表。

因此,如果 Outlet A 今天创建了签到记录,但 Outlet B 没有签到,因此没有记录,则 Outlet B 将被返回.

如果我们这么说:

@checkin_outlet_name = Checkin.where('DATE(created_at) = ?', Date.Today).outlet.name

@outlet = Outlet.all

理论上我可以找到今天没有签到的所有奥特莱斯,因为所有在 @outlet 中而不在 @checkin_outlet_name 上的记录都是那些我正在寻找。

但是,我不知道如何在 Rails 中实现这一点。

任何帮助将不胜感激。

【问题讨论】:

    标签: ruby-on-rails-3 analytics


    【解决方案1】:

    你可能想要Outlet.joins(:checkins).where("DATE(checkins.created_at) <> ?", Date.today)之类的东西

    【讨论】:

    • 不,我以前没试过这个。 ' 是什么?意思是?我很抱歉提出这样一个愚蠢的问题 - 但我是 Rails 的新手 :)
    • 我尝试了代码,但它似乎没有做我需要它做的事情。我需要获取今天尚未为其创建签到的网点列表。
    • 我打错了,应该是 Date.today,而不是 Date.Today。
    • 我已经更正了 Date.today 错误。但我不太清楚这应该做什么:(
    • 运算符的意思只是不同于 - 你想要的日期不等于今天的日期。
    【解决方案2】:

    如果你想在不编写复杂查询的情况下做到这一点,

    class Outlet
      scope :checked_in_today, { joins(:checkins).where("DATE(checkins.created_at) = ?", Date.today) }
    end
    
    # remove items from Outlet.all which have been checked in today (Array - Array)
    @not_checked_in_today = Outlet.all - Outlet.checked_in_today
    

    在 DB 中更好的方法

    class Outlet
      scope :not_checked_in_today, lambda {
        joins("LEFT OUTER JOIN (SELECT * FROM checkins WHERE created_at = #{Date.today.to_s(:db)}) c ON outltes.id = c.outlet_id"). #only select checkins created today
        where("c.outlet_id IS NULL"). # only keep outlets not checked in today
        select("DISTINCT outlets.*") # remove duplicates 
      }
    end
    
    @not_checked_in_today = Outlet.not_checked_in_today
    

    【讨论】:

    • 我收到以下错误:/app/models/outlet.rb:19: syntax error, unexpected '\n', expecting tASSOC 这听起来确实像我正在寻找的解决方案,我希望它有效。
    • 我很久没有使用 ActiveRecord,所以语法可能有点不对劲。尝试删除花括号。
    • 字符串插值中还有一个额外的花括号。
    • 我假设 { 应该以 lambda 为前缀是否正确?
    • 并非总是如此,但在这种情况下是的。 lambda 通常用于延迟代码的运行,直到实际调用范围。再次查看解决方案,我觉得您在这里需要lambda { .. }。否则在您的生产环境中,Date.today 将在应用程序启动时计算并被缓存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    相关资源
    最近更新 更多