【问题标题】:Rails Query a List for a CRON JobRails 查询 CRON 作业的列表
【发布时间】:2020-03-05 04:52:01
【问题描述】:

我是 CRON 工作的新手,但我认为我的设置正确。

最终我要做的是每天早上 8:00 向过去 3 天内未登录、未收到电子邮件且已标记的用户(和其他几个人)发送一封电子邮件作为活动或临时状态。

所以通过在控制台中查询数据库我知道我可以做到:

  • first = User.where(status: 'active').or(User.where(status: 'temp'))
  • second = first.where("last_login_at
  • 第三个 = second.where(notified: false)

这不一定是干净的,但我正在努力寻找一个包含所有数据的包含查询。 有没有更简洁的方法来做这个查询?

我相信我已经使用跑步者正确设置了我的 cron 作业。我已经安装了,并且在我的 schedule.rb 中我有:

every 1.day, at: '8:00 am' do
 runner 'ReminderMailer.agent_mailer.deliver'
end

所以在 app > mailer 我创建了 ReminderMailer

class ReminderMailer < ApplicationMailer
 helper ReminderHelper

 def agent_reminder(user)
  @user = user
  mail(to: email_recipients(user), subject: 'This is your reminder')
 end

 def email_recipients(agent)
  email_address = ''
  email_addresses += agent.notification_emails + ',' if agent.notification_emails
  email_addresses += agent.manager
  email_address += agent.email
 end
end

我真正苦苦挣扎的地方是我应该将查询发送到邮件程序的地方,这就是我构建 ReminderHelper 的原因。

module ReminderHelper

 def applicable_agents(user)
  agent = []
  first = User.where(status: 'active').or(User.where(status: 'temp'))
  second = first.where("last_login_at < ? ", Time.now-3.days)
  third = second.where(notified: false)
  agent << third
  return agent
 end
end

编辑:所以我知道理论上我可以进行一系列 where 查询。一定有更好的方法吧?

所以我需要帮助的是:我的结构是否正确?是否有更简洁的方法可以在 ActiveRecord 中为 CRON 作业查询这些数据?有没有办法测试这个?

【问题讨论】:

    标签: ruby-on-rails cron


    【解决方案1】:

    尝试将它们组合在一起,就像理解条件正确一样

    • 最近 3 天内未登录,
    • 没有收到邮件
    • 被标记为活动或温度为状态
    User.where("last_login_at < ? ", 3.days.ago).
         where(notified: false).
         where(status: ['active', temp])
    
    
    module ReminderHelper
     def applicable_agents(user)
       User.where("last_login_at < ? ", 3.days.ago).
         where(notified: false).
         where(status: ['active', temp])
     end
    end
    

    您不需要将它们添加/分配给数组。因为这个关系已经像一个数组了。如果需要数组,可以使用.to_a。如果您只想遍历它们,那么 users.each 应该可以正常工作。

    更新

    class User
    
        scope :not_notified, -> { where(notified: false) }
        scope :active_or_temp, -> { where(status: ['active', 'temmp']) }
        scope :last_login_in, -> (default_days = 3) { where("last_login_at < ?", default_days.days.ago) }
    
    end
    

    然后使用

        User.not_notified.active_or_temp.last_login_in(3)
    

    最好使用3.days.ago 而不是Time.now-3.days,因为它还考虑了时区,避免了不必要的麻烦和失败的测试用例。

    此外,您还可以创建小范围并将它们组合起来。更多阅读范围https://guides.rubyonrails.org/active_record_querying.html

    【讨论】:

    • 有一个 SyntaxError: unexpected ', ', expecting => "last_login_at
    • User.where("last_login_at &lt; ? ", 3.days.ago).where(notified: false).where(status: ['active', temp]) 试试这个
    • 我最终得到了 User.where(status: ["active", "temp"], notify: false).where("last_login_at
    • 为您更新答案
    • 不久前我实际上正在研究使用范围。除非我尝试运行它,否则我会在第一个范围内得到未定义的方法。另外,我仍然需要找出一些其他查询,这些查询涉及我正在考虑的其他一些表。
    猜你喜欢
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2014-02-07
    • 2018-03-26
    • 2020-06-29
    • 1970-01-01
    • 2016-07-23
    • 2017-07-06
    相关资源
    最近更新 更多