Ошибка Rails при попытке отправки почты нескольким пользователям - PullRequest
0 голосов
/ 02 февраля 2010

Я пытаюсь использовать плагин Whenever для рельсов для выполнения процесса модели в определенные моменты времени.

Когда я пытаюсь использовать процесс mail_out в моей модели User, я получаю следующую ошибку. Может ли кто-нибудь, пожалуйста, указать мне в правильном направлении, что идет не так?

/var/lib/gems/1.8/gems/rails-2.3.5/lib/commands/runner.rb:48: /var/lib/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:380:in `load_without_new_constant_marking': /home/tnederlof/Dropbox/Ruby/daily_trailer/app/models/user.rb:9: syntax error, unexpected tIDENTIFIER, expecting ')' (SyntaxError) @users = find(:all, :conditions => "#{weekday}sub = "t"")

Мой schedule.rb выглядит следующим образом:

   every 1.day, :at => '5:30 am' do
    runner "User.mail_out"
  end

Модель моего пользователя:

class User < ActiveRecord::Base

  acts_as_authentic

  def self.mail_out

    weekday = Date.today.strftime('%A').downcase

    @users = find(:all, :conditions => "#{weekday}sub = t")


    @users.each { |u| UserMailer.deliver_mail_out(u)}   


  end

end

Мой User_mailer:

class UserMailer < ActionMailer::Base
    def mail_out(users)
    @recipients = { }
    users.each do |user|
      @recipients[user.email] = { :name => user.name }
    end


    from        "no-reply@dailytrailer.net"
    subject     "Check out the trailer of the day!"
    body        :user => user
  end

end

Миграция:

  create_table "users", :force => true do |t|
    t.string   "email"
    t.date     "birthday"
    t.string   "gender"
    t.string   "zipcode"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "crypted_password"
    t.string   "password_salt"
    t.string   "persistence_token"
    t.string   "mondaysub",         :default => "f", :null => false
    t.string   "tuesdaysub",        :default => "f", :null => false
    t.string   "wednesdaysub",      :default => "f", :null => false
    t.string   "thursdaysub",       :default => "f", :null => false
    t.string   "fridaysub",         :default => "f", :null => false
    t.string   "saturdaysub",       :default => "f", :null => false
    t.string   "sundaysub",         :default => "f", :null => false
  end

1 Ответ

1 голос
/ 02 февраля 2010

Изменить эту строку

@users = find(:all, :conditions => "#{weekday}sub = t")

до

@users = find(:all, :conditions => ["#{weekday}sub = t"])

Ключ условия для метода find принимает в качестве значения массив или хэш. Если вы используете массив, то первый элемент массива сразу преобразуется в выражение sql «где», если у вас нет каких-либо знаков вопроса, и если он у вас есть, то эти знаки вопроса заменяются другими элементами массива. Например, если изменить вышеуказанное на знак вопроса, то оно станет

@users = find(:all, :conditions => ["#{weekday}sub = ?", 't'])

когда 't' это строка

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

Вы также можете записать свой запрос в хеш-условия, например

@users = find(:all, :conditions => {"#{weekday}sub".to_sym => 't'})

Большинство людей предпочитают это по сравнению с системой обозначений массива, другими словами, считают это рельсовым способом сделать это.

И еще один момент, глядя на ваш метод рассылки UserMailer #, вам не нужно делать

@users.each { |u| UserMailer.deliver_mail_out(u)}

в вашем методе User.mailout вы можете просто сделать

UserMailer.deliver_mail_out(@users)

потому что вы уже извлекаете каждый пользовательский объект из массива users в вашей рассылке UserMailer # и добавляете их получателям.

...