【问题标题】:Custom Model Method, setting scope for automatic sending of mail自定义模型方法,设置自动发送邮件的范围
【发布时间】:2012-04-10 20:29:35
【问题描述】:

这有几个阶段,由于我对 Rails 比较陌生,我不确定我是否以最好的方式来解决这个问题。

用户关注公司,公司申请在特定日期打开和关闭。如果用户关注一家公司,我希望他们在以下情况下自动收到电子邮件:a) 公司申请打开,b) 公司申请关闭前一周,c) 公司申请关闭当天。

我尝试过使用命名范围。我有以下模型方法(我认为这需要一些工作)设置每个公司的范围,具体取决于日期。

模型公司.rb

   def application_status
     if open_date == Today.date
      self.opening = true
     else
      self.opening = false
     end 

    if ((close_day - Today.date) == 7)
     self.warning = true
      else
     self.warning = false
    end 

    if close_day == Today.date
     self.closing = true
      else
     self.closing = false
    end 
 end

我希望每天对每个公司调用一次此方法,以便每个公司都有适当的范围 - 所以我尝试使用when gem (cron) 和以下代码。在每家公司上运行上述模型方法。

Schedule.rb

every 1.day do 
 runner "Firm.all.each do |firm|
  firm.application_status
 end"
end

然后对于每个范围的打开、警告、关闭,我在无论何时调度文件中都有一个方法,为简单起见,我将只显示打开方法。以下查询适用于所有已应用开放范围的公司,并对其运行 application_open_notification 方法。

Schedule.rb

every 1.day do
 runner "Firm.opening.each do |firm|
  firm.application_open_notification
 end"
end

这会调用 Firm.rb 模型中的以下方法

def application_open_notification
  self.users.each do |user|
   FirmMailer.application_open(user, self).deliver
  end
end

这又称为拼图的最后一块……应该向用户发送一封电子邮件,其中包括公司的名称。

def application_open(user,firm)
  @firm = firm
  @user = user
    mail to: @user.email, subject: @firm' is now accepting applications'
  end
 end

这是解决此问题的可行方法吗?特别是我对模型中的编码不是很熟悉。

非常感谢您提供的任何帮助。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 actionmailer named-scope rails-models


    【解决方案1】:

    我猜openingwarningclosing 是数据库字段,您的范围如下:

    class Firm < ActiveRecord::Base
        scope :opening, :where => { :opening => true }
        # etc
    end
    

    对于数据库(以及所有存储)有一个通用规则:如果不需要,不要存储可以计算的东西。

    由于应用程序的状态可以从当天的日期和open_dateclose_day 字段确定,因此您可以根据需要计算它们,而不是为它们创建额外的字段。您可以使用 SQL 和 Active Record 来做到这一点:

    scope :opening, :where { :open_date => (Date.today .. Date.today+1) }
    scope :warning, :where { :close_day => (Date.today+7 .. Date.today+8) }
    scope :closing, :where { :close_day => (Date.today .. Date.today+1) }
    

    (请注意,这些选择时间范围。根据您使用的是date 还是time 字段,可能需要更改它们。)

    但是还有另一个问题:如果由于某种原因(计算机崩溃、代码错误等)您的计划程序没有在特定日期运行,会发生什么情况?即使出现问题,您也需要一种确保最终发送通知的方法。有两种解决方案:

    1. 编写您的日程安排程序,可选择接受今天以外的日期(通过ARGV
    2. 为每家公司保留标志,以了解是否已发送每种通知。这些必须存储在数据库中。

    请注意,范围不是必需的。你可以这样做:

    Firm.where(:open_date => (Date.today .. Date.today+1)).each do |firm|
       #...
    end
    

    但范围至少封装了识别各种记录集的细节。

    【讨论】:

    • 我认为您跳过范围和创建模型方法的想法非常简洁,然后我可以每天调用一次。谢谢你,这真的是一个很大的帮助!
    猜你喜欢
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多