2013-07-29 6 views
1

Мое приложение включает людей, которые приходят на домашнюю страницу, вводят имя ставки, которую они сделали (для удовольствия), их адрес электронной почты, дату, на которую они хотели бы напоминать, и некоторые подробнее о ставке. Я использую каждый раз, когда этот камень запускается один раз в день.Отправка писем в выбранные пользователем даты

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: "[email protected]" 

    def bet_reminder(bet) 
    @bet = bet 

    mail to: bet.email, subject: bet.name + " Reminder" 
    end 
end 

я был успешным я n имеет электронные письма, отправленные, когда current_date соответствует дате, на которую они хотели напомнить (напоминание). Чтобы проверить это, я пошел в консоли рельсы, и выбран конкретный объект 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 protected]", 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 protected]", 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 protected]", 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 protected]", 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">] 

После того, как терминал завершает выше, мой почтовый ящик полон всех объектов Bet, которые имеют свое напоминание = current_date. Это доказывает, что настройки 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/[email protected]/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start' 
    from /Users/bvlaar/.rvm/gems/[email protected]/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start' 
    from /Users/bvlaar/.rvm/gems/[email protected]/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> 

«

Кроме того, когда я бегу» расслоение Exec когда это 'команда в терминале, ничего, кажется, не отправляется.

+0

Просьба поделиться с вами кодом, который вы используете в консоли, чтобы «[запустить] метод check_bet для всех объектов ставки». Кроме того, действительно ли сообщение об ошибке, которое вы получили, заканчивается на '# <>' или вы что-то оставили между '<>'? –

+0

@PeterAlfvin Я добавлю это к своему сообщению.Нет, я просто подумал, что хэш не имеет значения. Спасибо – Questifer

+1

'# <>' - это нотация объекта Ruby, что особенно актуально в этой ситуации, поскольку оно расскажет вам об объекте, который был отправлен методом 'check_bet'. –

ответ

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

Вы также можете сделать 'Bet.all.each (&: check_bet)'. –

0
  1. когда просто драгоценный камень, который поможет вам создать задачи хрон, он не будет запускать любые запланированные задачи для вас, кронтаба делает.

  2. Я думаю, что это будет лучше для запуска планировщика в час, как этот

    every :hour do 
        runner "Bet.check_bet" 
    end 
    
  3. Тогда в вашей 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 
    

Спасибо

 Смежные вопросы

  • Нет связанных вопросов^_^