我的应用程序涉及人们进入主页,输入他们所做的赌注的名称(为了好玩),他们的电子邮件地址,他们想要提醒的日期以及有关赌注的一些细节。我正在使用每当宝石来运行一次。
bet.rb
class Bet < ActiveRecord::Base
attr_accessible :details, :email, :name, :reminder, :sent
# Sends user a reminder if current_date is equal to the reminder date of the bet
def check_bet
current_date = Time.now.strftime("%Y-%m-%d").to_s
@bets = Bet.all
@bets.each do |bet|
BetMailer.bet_reminder(bet).deliver and bet.sent = true and bet.save! if bet.reminder.to_s == current_date
end
end
end
schedule.rb
every :day, :at => '5:00pm' do
runner "Bet.check_bet"
end
bet_mailer.rb
class BetMailer < ActionMailer::Base
default from: "from@example.com"
def bet_reminder(bet)
@bet = bet
mail to: bet.email, subject: bet.name + " Reminder"
end
end
当current_date等于他们想要提醒的日期(提醒)时,我已成功发送电子邮件。为了测试这个,我进入了rails控制台,并选择了一个特定的Bet对象,并使用以下命令运行check_bet方法:
1.9.2p320 :013 > Bet.last.check_bet
Bet Load (2.8ms) SELECT "bets".* FROM "bets" ORDER BY "bets"."id" DESC LIMIT 1
Bet Load (0.9ms) SELECT "bets".* FROM "bets"
(0.2ms) BEGIN
(0.3ms) COMMIT
(0.2ms) BEGIN
(0.3ms) COMMIT
(0.2ms) BEGIN
(0.2ms) COMMIT
=> [#<Bet id: 3, name: "Newsroom", email: "email@email.com", reminder: "2013-07-30", details: "Mac and Will are going to get back together.", sent: false, created_at: "2013-07-29 17:23:13", updated_at: "2013-07-29 17:23:13">, #<Bet id: 4, name: "Testing", email: "email@email.com", reminder: "2013-07-29", details: "This is a test", sent: true, created_at: "2013-07-29 18:38:42", updated_at: "2013-07-29 20:17:34">, #<Bet id: 5, name: "Cheaper iPhone", email: "email@email.com", reminder: "2013-07-29", details: "I bet Dad that there will be a cheaper iphone in th...", sent: true, created_at: "2013-07-29 20:39:33", updated_at: "2013-07-29 20:50:14">, #<Bet id: 6, name: "My grades", email: "email@email.com", reminder: "2013-07-29", details: "My grades this year will be > 84% average", sent: true, created_at: "2013-07-29 20:56:18", updated_at: "2013-07-29 21:14:21">]
终端完成上述操作后,我的电子邮箱中充满了所有提醒他们的提醒= current_date的Bet对象。这证明SMTP设置正常,我的视图中的代码工作正常。
但是,当我尝试在所有下注对象上运行check_bet方法时,我收到一个未定义的方法错误:
1.9.2p320 :016 > Bet.all.check_bet
Bet Load (1.8ms) SELECT "bets".* FROM "bets"
NoMethodError: undefined method `check_bet' for #<Array:0x007ffdd2c8c6c0>
from (irb):16
from /Users/bvlaar/.rvm/gems/ruby-1.9.2-p320@rails3tutorial/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
from /Users/bvlaar/.rvm/gems/ruby-1.9.2-p320@rails3tutorial/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
from /Users/bvlaar/.rvm/gems/ruby-1.9.2-p320@rails3tutorial/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>
另外,当我在终端中运行'bundle execnever'命令时,似乎没有任何东西被发送。
答案 0 :(得分:2)
Bet.all
会返回Array
,但未定义check_bet
方法。要在check_bet
的每个实例上调用Bet
,您需要执行Bet.all.each {|bet| bet.check_bet}
或清除Bet.all.each(&:check_bet)
(向@Ryan Bigg点头)。
有关性能方面的考虑,另请参阅http://guides.rubyonrails.org/active_record_querying.html#retrieving-multiple-objects-in-batches。
答案 1 :(得分:0)
只要只是一个帮助您生成cron任务的gem,它就不会为您运行任何计划任务, crontab 会这样做。
我认为最好每小时运行一次调度程序
every :hour do
runner "Bet.check_bet"
end
然后,在你的Bet模型课中,你可以这样做:
class Bet < ActiveRecord::Base
attr_accessible :details, :email, :name, :reminder, :sent
# Sends user a reminder if current_date is equal to the reminder date of the bet
def self.check_bet
current_date = Time.now.strftime("%Y-%m-%d").to_s
self.where(:reminder => current_date).each do |bet|
BetMailer.bet_reminder(bet).deliver # later you can use some background job gem like sidekiq, rescue or delayed_job to send email, otherwise the performance might be a issue
bet.update_attribute(:sent, true)
end
end
end
end
由于