开发者

Rails 3, Action Mailer, attachments and validations of email contents

开发者 https://www.devze.com 2023-03-08 07:11 出处:网络
I\'ve made a simple form for sending emails with attachments. The problem is that I don\'t know how to make it work in the mailer. All tutorials that I\'ve found so far are covering the scenario when

I've made a simple form for sending emails with attachments. The problem is that I don't know how to make it work in the mailer. All tutorials that I've found so far are covering the scenario when the file for the attachment is already somewhere one the server and I wasn't able to find anything about validating email contents.

So, I've got 2 questions for you:

  1. How can I let users send emails with attachments uploaded by them?
  2. How can I validate user's inputs and extensions of attachments?

My email form...

<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' %>

and my mailer...

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

I came up with attachments[file.original_filename] =File.read(file.path) and it's adding attachments but the files are coruppted and cannot be opened...

Any thoughts or links would be greatly appreciated.


I've found that if you want to send email with attachment in rails, you need to attach it that way...

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

So the whole mailer method might look like this...

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

As for the validations, there are two methods that I've found. First one is quite obvious. You have to create a table in your database and validate form's inputs in model just like you always do. If you do it that way than everything will be saved in your database. It has some advantages, for exmple: you can use it as an archive or for some kind of statistics about your clients in your app or even put it through some sql triggers. However, if you don't want to save anything than you can create "tableless model" (Railscasts #193 and original Codetunes). All you have to do is to place this code at the begining of your model:

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

Than you have to list your columns...

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

And after that you can place your model's code...

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..."

Right now, I'm using Gmail for sending emails but it's quite slooow. It takes about 2 minutes to send a short message with 2Kb test attachment. Have you got any suggestions about how to speed up this process? Maybe you can recomend another provider or solution?

PS. Don't forget to check out 'client side validations' Railscasts #263

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号