Rails如何创建一个可以通过浏览器和cron作业使用的方法

时间:2013-01-14 23:36:14

标签: ruby-on-rails ruby ruby-on-rails-3 cron whenever

我创建了一个名为get_primary_email(user)的方法,它位于我的application_controller.rb文件中。

现在我在我的应用程序中使用此方法,以及调用使用get_primary_email(user)的方法的cron作业

我的问题是,如果我将方法定义为:

def get_primary_email(user)
end

它在我的应用程序中运行得很好,但是cron作业出错了。

如果我将方法定义为:

def self.get_primary_email(user)
end

我的cron作业有效,但是通过浏览器调用get_primary_email(user)的每个方法都失败了。

我如何在两个地方使用同样的方法?

修改

schedule.rb

set :output, "#{path}/log/cron.log"

every 1.day, :at => "8:00pm" do
  runner "BirthdayRemindersController.send_birthday_email_reminders"
end

2 个答案:

答案 0 :(得分:2)

这通常是通过设置一个cron作业来调用rake任务来完成的。在rake任务中,您可以轻松调用Rails代码。

网上有很多例子。这是SO中的一个:

A cron job for rails: best practices?

编辑 - 添加Resqueue代码和Mailer示例

user.rb

class User

  scope :birthday_today, lambda { where('birthday = ?', Date.today) }

  def self.send_birthday_alerts
    self.birthday_today.each do |user|
      BirthdayAlertJob.enqueue(user.id)
    end
  end

  def get_primary_email
    ...
  end

end

作业/ birthday_alert_job.rb

class BirthdayAlertJob
  @queue = :birthday_alert

  def self.perform(u_id)
    user = User.find(u_id)
    UserMailer.birthday_alert(@user).deliver
  end
end

schedule.rb

every 1.day, :at => "8:00pm" do
  rake "users:send_birthday_alerts"
end

users.rake

namespace :users do
  desc "Queue up Birthday Alerts"
  task :send_birthday_alerts => :environment do
    User.send_birthday_alerts
  end
end

user_mailer.rb

class UserMailer < ActionMailer::Base

  def birthday_alert(user)
    mail(to: user.primary_email, subject: "Happy Birthday")
    ...
  end
end

这是接近的,未经测试的等等。我知道您需要做的一件事是确保用户尚未收到电子邮件。现在不确定你是怎么做的。另一列可以保留警报排队的最后一次。

答案 1 :(得分:1)

根据您发布的内容,我建议这样的内容:

<强> LIB / birthday_reminders.rb:

class BirthdayReminders
  def self.send_birthday_email_reminders
    # code ...
  end

  def self.primary_email_for(user)
    # code ...
  end
end

<强>控制器/ application_controller.rb:

class ApplicationController < ActionController::Base
  def get_primary_email(user)
    BirthdayReminders.primary_email_for(user)
  end
end

<强> SOMEWHERE / schedule.rb:

set :output, "#{path}/log/cron.log"

every 1.day, :at => "8:00pm" do
  runner "BirthdayReminders.send_birthday_email_reminders"
end