Rails 3, Action Mailer, вложения и проверки содержимого электронной почты - PullRequest
0 голосов
/ 26 мая 2011

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

Итак, у меня есть к вам 2 вопроса:

  1. Как разрешить пользователям отправлять электронные письма с загруженными ими вложениями?
  2. Как я могу проверить вводимые пользователем данные и расширения вложений?

Моя электронная почта ...

<div id="form_wrapper">
  <%= form_for(:kontakt, :url => {:action => 'kontakt'}, :html => { :multipart => true }, :remote=>true) do |f| %>
  <ul>
    <li>
      <%= f.label(:email) %>
      <%= f.text_field(:email) %>
    </li>
    <li>
      <%= f.label(:content) %>
      <%= f.text_area(:content, :size => "42x7") %>
    </li>
    <li>
      <%= f.label(:preview, :class=>:preview )%>
      <%= f.file_field :preview %>
    </li>
  </ul>
  <%= image_submit_tag("blank.gif",:id=>"send_email", :class=>"action submit") %>
  <%= link_to("Reset", {:controller=>'frontend',:action => 'index'},:remote => true, :class => 'action reset') %>
 <% end %>
</div>
<%= javascript_include_tag 'jquery.form.js','jquery.rails','jquery.remotipart' %>

и мой почтовик ...

class Contact < ActionMailer::Base
  default :from => "xxxxx@gmail.com"
  def wiadomosc(email)
    @content=email[:content]
    file=email[:preview]
    attachments[file.original_filename] =File.read(file.path)
    mail(
      :subject=>"www.XXXXXX.pl - you've got a new message",
      :reply_to =>"xxxxx@gmail.com",
      :to => email[:email]
    )
  end
end

Я придумал attachments[file.original_filename] =File.read(file.path), и он добавляет вложения, но файлы повреждены и не могут быть открыты ...

Любые мысли или ссылки будут с благодарностью.

1 Ответ

7 голосов
/ 16 июля 2011

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

attachments[file.original_filename] = File.open(file.path, 'rb'){|f| f.read}

Так что весь метод почтовой программы может выглядеть следующим образом

def message(email)
  @content=email[:content]
  unless email[:email_attachment].nil?
    file=email[:email_attachment]
    attachments[file.original_filename] = File.open(file.path, 'rb'){|f| f.read}
  end
  mail(
    :subject=>"www.XXXXXX.pl - you've got a new message",
    :reply_to =>"xxxxx@gmail.com",
    :to => email[:email]
  )
end

Что касается проверок, я нашел два метода.Первый вполне очевиден.Вы должны создать таблицу в своей базе данных и проверить входные данные формы в модели, как вы всегда делаете.Если вы сделаете это таким образом, то все будет сохранено в вашей базе данных.Например, у него есть некоторые преимущества: вы можете использовать его в качестве архива или для какой-то статистики о ваших клиентах в вашем приложении или даже использовать некоторые триггеры sql.Однако, если вы не хотите сохранять что-либо, вы можете создать «модель без таблиц» ( Railscasts # 193 и оригинальную Codetunes ).Все, что вам нужно сделать, это поместить этот код в начале вашей модели:

def self.columns() @columns ||= []; end

def self.column(name, sql_type = nil, default = nil, null = true)
  columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
end

Чем вы должны перечислить свои столбцы ...

column :name, :string
column :company, :string
column :email, :string
column :content, :text
column :type_of_question, :string
column :email_attachment, :string

И после этого вы можетепоместите код вашей модели ...

has_attached_file :email_attachment

EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
TYPES = ['application/zip', 'multipart/x-zip',  'application/x-zip-compressed']

validates :name,  :presence  => {:message => "Blah blah blah"}
validates :email, :presence  => {:message => "Blah blah blah"},
                  :format=>{:unless=>  Proc.new{|s| s.email.nil?|| s.email.empty?  },
                            :with => EMAIL_REGEX, :message => "Blah blah blah"}
validates :content, :presence  => {:message => "Blah blah blah"}
validates_inclusion_of :type_of_question, :in => ["Blah1", "Blah2", "Blah3"],
                       :message => "%{value} is not on the list of types"
validates_attachment_content_type :email_attachment, :content_type => TYPES,
                                  :message =>  "The attachment has wrong extension..."

Прямо сейчас я использую Gmail для отправки электронных писем, но он довольно медленный.Для отправки короткого сообщения с тестовым вложением 2Кб требуется около 2 минут.Есть ли у вас какие-либо предложения о том, как ускорить этот процесс?Может быть, вы можете порекомендовать другого поставщика или решение?

PS.Не забудьте проверить «проверки на стороне клиента» Railscasts # 263

...