Не удается заставить Rails 3 ActionMailer принять вложение - PullRequest
0 голосов
/ 11 февраля 2012

Я перевожу приложение Rails 2.3.14 на Rails 3.0.В нем почтовик отправляет сообщение с вложением.Используя код ниже, это работало без проблем в 2.3.x.

def notification(material, recipient, path_to_file)  
  enctype = "base64"

  @recipients  = recipient.email
  @from        = material.person.email
  @reply_to    = material.person.email
  @subject     = "New or updated materials: " + material.name
  @sent_on     = Time.now
  @content_type = "multipart/mixed"
  @headers['sender'] = material.person.email

  part    :content_type => "text/plain", 
          :body => render_message('notification', 
          :material => material, 
          :url =>  material.full_url_to_material)

  attachment  :content_type => "application" + "/" + material.file_type, 
              :body => File.read(path_to_file), 
              :filename => File.basename(material.file),
              :transfer_encoding => enctype, 
              :charset => "utf-8" if !!material.send_as_attachment

end

Чтение через Rails 3.0 Инструкции ActionMailer , я изменил метод следующим образом:

  def notification(material, recipient, path_to_file)
    @material = material
    @url = material.full_url_to_material
    attachments[material.file_file_name] = File.open(path_to_file, 'rb'){|f| f.read} if material.send_as_attachment?
    headers['sender'] = material.person.email
    mail(:to => recipient.email,
         :subject => "New or updated materials: " + material.name,
         :reply_to => material.person.email, 
         :from =>  material.person.email)
  end

MaterialMailer # уведомление вызывается, когда материалсоздано.У меня есть следующая спецификация, чтобы проверить это:

  it "will include the materials as an attachement with the the send_as_attachment field is set to 1" do
    it = Material.create(@materials_hash.merge(:send_notification => "1", :send_as_attachment => "1"))
    email =  ActionMailer::Base.deliveries[0] 
    email.body.should =~ Regexp.new("Name of the posted material: " + it.name )
    email.has_attachments?.should be_true
  end

Как я уже говорил, это работало нормально в 2.3.Теперь, если я установлю флаг send_as_attachment в единицу, я получу следующую ошибку, ссылаясь на строку email.body.should:

  1) Material will include the materials as an attachement with the the send_as_attachment field is set to 1
     Failure/Error: email.body.should =~ Regexp.new("Name of the posted material: " + it.name )
       expected: /Name of the posted material: My material/
            got:  (using =~)
       Diff:
       @@ -1,2 +1 @@
       -/Name of the posted material: My material/

Если я изменю спецификацию и установлю send_as_attachment в 0, я получуследующая ошибка, ссылающаяся на has_attachments?строка:

1) Материал будет включать материалы, так как в качестве вложения в поле send_as_attachment установлено значение 1 Сбой / Ошибка: email.has_attachments?в том числе вложение как-то ломает письмо.

Я пробовал другие способы прикрепления материала:

  attachments[material.file_file_name] =  {:mime_type => "application" + "/" + material.file_content_type, 
              :content => File.read(material.file.path),  
              :charset => "utf-8"}

Я пробовал жестко задавать пути к известным файлам.Но не повезло.

Где-нибудь еще, где я должен искать?

1 Ответ

0 голосов
/ 11 февраля 2012

Согласно предложению Кристофера, вот код почтовой программы и спецификации, которые я использовал, чтобы заставить его работать:

  def notification(material, recipient, path_to_file)
    @material = material
    @url = material.full_url_to_material
    attachments[material.file_file_name] = File.open(material.file.path, 'rb'){|f| f.read} if material.send_as_attachment?
    headers['sender'] = material.person.email
    mail(:to => recipient.email,
         :subject => message_subject("New or updated materials: " + material.name),
         :reply_to => material.person.email, 
         :from =>  material.person.email)
  end

  it "will include the materials as an attachment with the the send_as_attachment field is set to 1" do
    it = Material.create(@materials_hash.merge(:send_notification => "1", :send_as_attachment => "1"))
    Delayed::Worker.new(:quiet => true).work_off
    email =  ActionMailer::Base.deliveries[0] 
    email.parts.each.select{ |email| email.body =~ Regexp.new("Name of the posted material: " + it.name )}.should_not be_empty
    email.has_attachments?.should be_true
  end

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

...