检查关联模型开始日期是否在任务中的下一个24小时内

时间:2014-08-12 05:53:36

标签: ruby-on-rails ruby ruby-on-rails-4 actionmailer

我遇到了这项任务的问题。基本上我只想向用户发送每日电子邮件,如果他们是高级会员(有效期限不为NULL的用户),他们会在接下来的24小时内收到提醒。

模型看起来像这样:

class Reminder < ActiveRecord::Base
  belongs_to :user

  default_scope { order('start DESC') }
end

class User < ActiveRecord::Base
  has_many :reminders    
end

我已经开始完成这项任务,但我很难理解它。这是我到达的地方,这会引发错误。

task :reminder => :environment do
  @users_mailed = User.where(:expiry != 'NULL')
  #expiry is set when someone becomes a premium member

  @users_mailed.each do |user|
     if user.reminder.where("start >= ?", DateTime.now).where("start <= ?", 1.day.from_now)
       ReminderMailer.daily_email(user).deliver
     end
  end
end

rake aborted!
NoMethodError: undefined method `reminder' for #<User:0x007fad14d06998>

邮件看起来像这样,如果我只是将用户传入其中,就会按照我想要的方式工作。

class ReminderMailer < ActionMailer::Base
  add_template_helper(ApplicationHelper)
  default from: "My Site <noreply@mysite.com>"

  def daily_email(user)
    @user            = user
    @user_reminders  = user.reminders.where("start >= ?", DateTime.now).where("start <= ?", 1.day.from_now)
    @timezone        = user.timezone
    @url             = 'mysite.com'
    mail(to: user.email, subject: 'Your reminders for ' + Time.now.strftime("%m/%d/%Y"))
  end 
end

如何让这项任务按照我想要的方式运作?

2 个答案:

答案 0 :(得分:1)

您使用助手has_many :reminders。这意味着rails会将方法.reminders添加到用户模型,而不是上面使用的.reminder。根据您要实现的目标,更改.reminder的所有.reminders次来电,并对其进行迭代或将has_many更改为has_one

答案 1 :(得分:1)

我认为有三件事可以使你的代码正确:

1 - 我无法使其发挥作用。

@users_mailed = User.where(:expiry != 'NULL')

使用:

@users_mailed = User.where.not(:expiry => nil) 
#or simply 
@users_mailed = User.where('expiry is NOT NULL')

2 - 由@FilipBartuzi曝光:

if user.reminder.where...

提醒中应该有's'。您在邮件程序方法中正确调用它的典型错字。

3 - 避免将DateTime.now和Time.now与1.day.from_now和stuff混合使用。您正在比较不同时区的时间。因为它会检查下一个24小时的提醒,例如,根据您当地的时区,您可以在27或23小时的间隔内检查提醒。 This link非常善于掌握我所说的概念。

干杯!