Action Mailer, attachmenty i walidacja zawartości maila

Witam,

Zrobiłem w railsach prosty formularz do wysyłania maili wraz z załącznikami. Problem w tym, że nie wiem jak to poprawnie potem obsłużyć w mailerze. Wszystkie tutoriale, poradniki jakie znalazłem opisują scenariusz, gdy załącznik jest plikiem znajdującym się już w którymś z folderów w naszej aplikacji.
Pyatania mam więc następujące:

  1. Jak to obsłużyć, aby użytkownik mógł sam dodawać załączniki ze swojego komputera?
  2. Jak wygląda sprawa z walidacją danych przesyłanych przez użytkownika? Jak sprawdzać czy wysyłany plik ma poprawne rozszerzenie?

Jak narazie doszedłem do następującego rozwiązania:

formularz

[code]


<%= form_for(:kontakt, :url => {:action => ‘kontakt’}, :html => { :multipart => true }, :remote=>true) do |f| %>


  • <%= f.label(:email) %>
    <%= f.text_field(:email) %>


  • <%= f.label(tresc) %>
    <%= f.text_area(:tresc, :size => “42x7”) %>


  • <%= f.label(:preview, :class=>:preview )%>
    <%= f.file_field :preview %>


<%= image_submit_tag(“blank.gif”,:id=>“send_email”, :class=>“action submit”) %>
<%= link_to(“Anuluj”, {:controller=>‘frontend’,:action => ‘index’},:remote => true, :class => ‘action reset’) %>
<% end %>
<%= javascript_include_tag 'jquery.form.js','jquery.rails','jquery.remotipart' %>[/code] mailer [code]class Contact < ActionMailer::Base default :from => "xxxxx@gmail.com" def wiadomosc(email) @content=email[:opis] file=email[:preview] attachments[file.original_filename] =File.read(file.path) mail( :subject=>"www.XXXXXX.pl - dostałeś nową wiadomość", :reply_to =>"xxxxx@gmail.com", :to => email[:email] ) end end[/code] ... załączniki są dostarczane, ale są w baardzo złej jakości(jeśli chodzi o zdjęcia). Pliki inne niż graficzne nie są dołączone w ogóle. Może to coś związanego z encoding?

Będę wdzieczny za wszelkie słowa krytyki, wyjaśnienia i linki.

Pzdr.

Udało mi się przeprowadzić walidację zawartości maila używając tableless model http://railscasts.com/episodes/193-tableless-model. Dalej jednak nie mogę sobie poradzić z dodawaniem do maila plików wczytywanych przez użytkownika :confused:

Czy ktoś z Was wie jak to zrobić?

U rayanb masz screencast o mailerze w rails 3 i jest tam dodawanie plików pokazane. Walidację zrób najlepiej w js. Ładna i szybka i od razu widać jej efekty a nie po przeładowaniu.

Widziałem już tego screencast’a, ale tak jak napisałem w pierwszym poście - załącznik w screencaście jest plikiem znajdującym się już w którymś z folderów w naszej aplikacji. Ja natomiast chciałbym, aby plik był wczytywany z formularza zatwierdzonego przez użytkownika.

Walidacja przy pomocy js nie jest złym pomysłem. Ja jednak wolę walidację po stronie serwera, odbierającą użytkownikowi możliwość edycji zabezpieczeń.

Ma ktoś jakieś inne sposoby albo linki na temat załączników?

[quote=Yaz]Walidacja przy pomocy js nie jest złym pomysłem. Ja jednak wolę walidację po stronie serwera, odbierającą użytkownikowi możliwość edycji zabezpieczeń.

Ma ktoś jakieś inne sposoby albo linki na temat załączników?[/quote]
Walidacje po stronie klienta powinno się robić na podstawie walidacji po stronie serwera:
http://railscasts.com/episodes/263-client-side-validations

A co do załączników jako plik podajesz plik z formularza (np params[:attachment]), bez modyfikacji albo z niewielkimi będzie działał w mailerze. Najlepiej podłącz debugger i sprawdź.

slawosz, próbowałem w mailerze zrobić tak jak piszesz:

attachments["zalacznik.zip"] = email[:zalacznik]

… ale w konsoli mi wyrzuciło:

NoMethodError (undefined method `length' for #<ActionDispatch::Http::UploadedFile:0x39ce4a8>): app/mailers/contact.rb:9:in `wiadomosc' app/controllers/frontend_controller.rb:48:in `kontakt'
linia 48 w frontend_controller odnosi sie do:

Contact.wiadomosc(params[:kontakt]).deliver

Na wszelki wypadek podsyłam również tableless’a ( może komuś się przyda, może ktoś zwróci mi uwagę na ewentualne błędy jakie popełniłem :wink: ):

[code]#encoding:utf-8
class Message < ActiveRecord::Base
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

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

column :imie_i_nazwisko, :string
column :firma, :string
column :email, :string
column :tresc_wiadomosci, :text
column :typ_projektu, :string
column :zalacznik_file_name, :string
column :zalacznik_content_type, :string

has_attached_file :zalacznik

validates :imie_i_nazwisko, :presence => {:message => “Podaj imię i nazwisko, aby udowodnić, że jesteś człowiekiem ;-)”}
validates :email, :presence => {:message => “Adres email musi być podany”},
:format=>{:unless=> Proc.new{|s| s.email.nil?|| s.email.empty? },
:with => EMAIL_REGEX, :message => “Adres email ma niepoprawny format”}
validates :tresc_wiadomosci, :presence => {:message => “Wiadomość musi zawierać jakąś treść”}
validates_inclusion_of :typ_projektu, :in => [“Nowa strona www”, “Modernizacja strony www”, “Nowy sklep internetowy”, “Statyczna strona www (bez CMS’a)”],
:message => “%{value} nie ma na liście typów projektu”
validates_attachment_content_type :zalacznik, :content_type => TYPES,
:message => “Załącznik ma nieprawidłowy format”
end[/code]

Tak na szybko:
attachments[“zalacznik.zip”] = email[:zalacznik].tempfile

Napisz czy pomogło.

Niestety nie pomogło :confused: Tym razem dostałem…

NoMethodError (undefined method `[]' for #<Tempfile:0x4c24ec0>): app/mailers/contact.rb:9:in `wiadomosc' app/controllers/frontend_controller.rb:48:in `kontakt'
Macie jeszcze jakieś pomysły?

Sesja mi się skończyła, więc ponownie zasiadłem do railsów i do nierozstrzygniętego problemu. Wskazówki znalazłem na jednym z zagranicznych forów. Wygląda na to, że kod…

unless email[:zalacznik].nil? file=email[:zalacznik] attachments[file.original_filename] = File.open(file.path, 'rb'){|f| f.read} end
… wysyła poprawnie maile z załącznikami.

Jak narazie wysyłam wszystko przez gmail’a. Wydajność nie jest zbyt imponująca. Mail z krótką treścią i 2 Kb załącznikiem wysyła się ok 1,5 minuty. Do tego google nie pozwala na zmianę nazwy nadawcy. To ostatnie zabezpieczenie jest logiczne, choć ciekaw jestem, czy znacie jakiegoś provider’a, który na to pozwala…

Zmienić sobie możesz, ale wielce pradopodobne że jako spam zostaniesz potraktowany. Jak adres nadawczy (domena) nie zgadza się z domeną serwera pocztowego to lecisz jako spam