Получение Actionmailer для отправки списка просроченных задач в rails3 - PullRequest
0 голосов
/ 30 июля 2011

Я пытаюсь отправить своим пользователям электронное письмо через cron, каждый со списком их задач.Я могу отправить электронное письмо каждому пользователю с просроченными задачами.В моем шаблоне электронной почты я могу отобразить ВСЕ просроченные задачи.Что я не могу сделать, так это перечислить только задачи конкретного пользователя.

Прежде всего, я создал область, которая находит всех пользователей с соответствующими задачами:

Users.rb

scope :tasksdue, lambda {
       joins("join tasks on tasks.user_id = users.id").
       where("tasks.dueddate >= ? AND tasks.status = ?", Date.today, false).
       group("users.id")
     }

Также в моей модели пользователей я нахожу и отправляю этим пользователям электронную почту:

def self.send_reminders
         User.tasksdue.find_each do |user|
         UserMailer.deliver_task_due user 
       end
end

И, на мой взгляд, у меня есть это:

<!DOCTYPE html>
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
  </head>
  <body>
    <h1>Hello! <%= @user.name %></h1>

    <% User.listtasks.find_each do |task| %>
  <li> <%= task.tasks.title %> </li>
<% end %>

  </body>

проблема состоит из задач должной части.Я вызываю область из модели моего пользователя:

 scope :listtasks, lambda {
   joins("join tasks on tasks.user_id = users.id").
   where("tasks.dueddate >= ? AND tasks.user_id = ? AND tasks.status = ?", Date.today, :id, false)       
}

Используя это, я получаю ошибку:

неопределенный метод `title 'для #

Я также пытался позвонить с Tasks.rb

 scope :tasksdue, lambda { 
     where("dueddate >= ? AND user_id = ? AND status = ?", Date.today, Task.user_id, false)
  }

, который жалуется на user_id.

Я могу получить его для перечисления всех глобальных просроченных задач, но не для пользователя.

Что мне нужно сделать, чтобы он перечислял только задачи для пользователя ??

- РЕДАКТИРОВАТЬ ---

Согласно совету @ ream88 ниже, я создал дванезависимых областей и в моем контроллере задач для открытых и просроченных:

scope :overdue, lambda { where('dueddate >= ?', Date.today) }
scope :open, where(:status => false)

Теперь я не знаю, как их перебирать.Я пробовал это в своем шаблоне actionmailer, но адрес электронной почты одинаков для каждого пользователя ...

<% Task.open.overdue.find_each do |task| %>
<%= task.title %>
<% end %>

Как я могу указать пользователя в этом запросе ??

1 Ответ

3 голосов
/ 30 июля 2011

Вы делаете много встроенных функционально самостоятельно, почему? Мое мнение:

Создайте ассоциацию has_many в вашей модели User и соответствующую ассоциацию belongs_to в вашей модели Task (если это еще не сделано):

# user.rb
has_many :tasks

# task.rb
belongs_to :user

И добавить следующие области к Task:

scope :overdue, lambda { where('dueddate >= ?', Date.today) }
scope :open, where(:status => false)

И теперь вы можете получить доступ к просроченным задачам для конкретного пользователя через: user.tasks.open.overdue. (Возможно, вы можете создать только одну область видимости в вашей Task модели, включающей оба критерия поиска, но я считаю, что нужно разбить мой код на мельчайшие части.)


# mailer.rb
def task_due(user)
  @user, @tasks = user, user.tasks.open.overdue
  mail(:to => user.mail, :subject => 'Do your work! Dammit!') do |as|
    as.html { render('your/email/partial') }
    as.text { render('your/email/partial') }
  end
end

# your/email/partial.html.erb
<% @tasks.each do |task| %>
  <li><%= task %></li>
<% end %>

# your/email/partial.text.erb
<% @tasks.each do |task| %>
  * <%= task %>
<% end %>

# models/user.rb
def self.send_mails_to_lazy_users
  # Remind lazy user about their tasks!
  # This function should be called in a controller, after a specific button was pressed or in a background task, like delayed_job
  includes(:tasks).where(:tasks => ['duedate >= ? AND status = ?', Date.today, false]).each do |lazy_user|
    Mailer.task_due(lazy_user)
  end
end
...