Converting old Mailer to Rails 3 (multipart/mixed) - ruby-on-rails

I'm having some difficulties converting this old mailer api to rails 3:
content_type "multipart/mixed"
part :content_type => "multipart/alternative" do |alt|
alt.part "text/plain" do |p|
p.body = render_message("summary_report.text.plain.erb",
:message =>
message.gsub(/<.br.>/,"\n"),
:campaign=>campaign,
:aggregate=>aggregate,
:promo_messages=>campaign.participating_promo_msgs)
end
alt.part "text/html" do |p|
p.body = render_message("summary_report.text.html.erb",
:message => message,
:campaign=>campaign,
:aggregate=>aggregate,:promo_messages=>campaign.participating_promo_msgs)
end
end
if bounce_path
attachment :content_type => "text/csv",
:body=> File.read(bounce_path),
:filename => "rmo_bounced_emails.csv"
end
attachment :content_type => "application/pdf",
:body => File.read(report_path),
:filename=>"rmo_report.pdf"
In particular I don't understand how to differentiate the different multipart options. Any idea?

"Action Mailer will automatically send multipart emails if you have different templates for the same action."
For example having these files would give you text and html versions:
summary_report.text.erb
summary_report.html.erb
Check the Rails Guides for details:
http://guides.rubyonrails.org/action_mailer_basics.html#sending-multipart-emails
http://guides.rubyonrails.org/action_mailer_basics.html#sending-emails-with-attachments

Related

How to send multiple ".Zip" files in ruby on rails

I am new to Ruby on Rails .I am working on project where I need to send multiple Zip files To client.
I am using RubyZip for this .
def Download
unless params[:fileLists].nil?
file_name = "Peep-#{Time.now.to_formatted_s(:number)}.zip"
t = Tempfile.new("my-temp-filename-#{Time.now.to_formatted_s(:number)}")
Zip::OutputStream.open(t.path) do |z|
for _file in params[:fileLists]
unless _file.empty?
if File.file? _file
#z.add(File.basename(_file),_file)
z.put_next_entry(File.basename _file)
z.print IO.read(_file)
#send_file _file , disposition: 'attachment',status: '200'
end
end
end
end
#Sending Zip file
send_file t.path, :type => 'application/zip',
:disposition => 'attachment',
:filename => file_name
t.close
end
end
end
This is Working fine for all other file formats except Zip files .How it can be done ?
I resolved it by modifying my method .I used IO.binread(_file) instead of IO.read(_file) to read file.
Zip::OutputStream.open(t.path) do |z|
for _file in params[:fileLists]
unless _file.empty?
if File.file? _file
#z.add(File.basename(_file),_file)
z.put_next_entry(File.basename _file)
z.print IO.binread(_file)
end
end
end
end
#Sending Zip file
send_file t.path, :type => 'application/zip',
:disposition => 'attachment',
:filename => file_name
rubyzip is a lib for creating / working with zip archives in ruby.
ยป gem install rubyzip
Sample code
require 'zip/zip'
require 'zip/zipfilesystem'
def download_all
attachments = Upload.find(:all, :conditions => ["source_id = ?", params[:id]])
zip_file_path = "#{RAILS_ROOT}/uploads/download_all.zip"
# see if the file exists already, and if it does, delete it.
if File.file?(zip_file_path)
File.delete(zip_file_path)
end
# open or create the zip file
Zip::ZipFile.open(zip_file_path, Zip::ZipFile::CREATE) { |zipfile|
attachments.each do |attachment|
#document_file_name shd contain filename with extension(.jpg, .csv etc) and url is the path of the document.
zipfile.add( attachment.document_file_name, attachment.document.url)
end
}
#send the file as an attachment to the user.
send_file zip_file_path, :type => 'application/zip', :disposition => 'attachment', :filename => "download_all.zip"
end

Rails logging from controller upload method

I am very new to Rails, and I can't understand how can I log something from a particular controller method. I implemented a simple file upload, with fileutils:
def file_upload
require 'fileutils'
require 'rest_client'
tmp = params[:file_upload][:my_file].tempfile
logger.info 'log information with logger'
puts 'log information with puts'
p 'log information with p'
file = File.join("public", params[:file_upload][:my_file].original_filename)
FileUtils.cp tmp.path, file
RestClient.post 'http://externalapi', :destination => 'address', :subject => 'subject', :file => file, :api_key => 'apikey'
end
but from within this method the logging doesn't works. However it does within any other method. I am using Ruby 1.9.3 and Rails 4

Requests spec post request No route matches error

I'm getting no route matches with rspec for testing a method in my controller.
Below is the test code:
let(:csv_file){ fixture_file_upload('files/sample_employee_data.csv', 'text/csv') }
describe "#process_csv" do
it "should output a valid csv file" do
post '/payslips/process_csv', :csv => csv_file, :header => 1
puts response
end
end
Below is my routes.rb file code:
PayCalculator::Application.routes.draw do
resources :payslips do
collection { post :process_csv }
end
root 'payslips#index'
end
Below is the method
def process_csv(uploaded_file = params[:files][:csv], headers = params[:files][:headers])
begin
rows = CSV_Manager.extract_csv(uploaded_file, headers)
rows.each do |row|
payslip = Payslip.create(
:first_name => row[0],
:last_name => row[1],
:annual_salary => row[2],
:superannuation => row[3].to_i,
:payment_start_date => row[4]
)
redirect_to root_url, notice: payslip.errors.full_messages and return unless payslip.valid?
prepare_output(row)
end
#rows = self.pay_data
csv_file = CSV_Manager.prepare_csv(#rows, ["Name", "Pay Period", "Gross Income", "Income Tax", "Net Income", "Superannuation"])
send_data csv_file, :type => 'text/csv; charset=iso-8859-1; header=present',
:disposition => "attachment;filename=Payslip #{Date.today.to_s}.csv"
rescue
redirect_to root_url, notice: "CSV not supplied or invalid format"
end
end
When I run rspec spec/ I get below error:
Failure/Error: post '/payslips/process_csv', :csv => csv_file, :header => 1
ActionController::UrlGeneratorError:
No route matches...
What could be wrong in here that is causing this error?
params[:files][:headers] where you are passing :header => 1. Key is different. This will not cause no route found probably but just for correction. As per rails convention action doesn't has parameters
If you are going to pass optional params in any methods: Please have a look at : http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_methods.html
Following is the example of method defination:
def foo(arg1="Miles", arg2="Coltrane", arg3="Roach")
"#{arg1}, #{arg2}, #{arg3}."
end
Try this:
post :process_csv, :files => {:csv => csv_file, :header => 1}

how do I use Rspec to test the contents of a textarea in a view?

I am writing a view spec with RSpec and I keep getting this problem. The test will find textarea but it fails when I try to test the contents. Any suggestions?
This is the test I am having trouble with.
describe "reminders/edit.html.erb" do
before(:each) do
#reminder = Factory(:reminder)
end
it "should render the form to edit a reminder" do
assign :reminder, #reminder
render
rendered.should have_selector("form", :method => "post", :action => reminder_path(#reminder) ) do |f|
f.should have_selector("input", :type => "text", :name => "reminder[title]", :value => "The Title" )
f.should have_selector("textarea", :name => "reminder[content]", :value => 'The big content')
f.should have_selector("input", :type => "submit")
end
end
I might be doing this all wrong since I am pretty new at TDD, but I am seeing that this test passes when I remove the value from the textarea which really confuses me. So is there a way to test a textarea for it's contents?
Textareas are different to input elements because their 'value' is their content rather than their value attribute, so should you be matching on the content instead? Try this:
f.should have_selector("textarea", :name => "reminder[content]", :content => 'The big content')

Rails - ActionMailer sometimes shows attachments before the email content?

How can I make it so ActionMailer always shows attachments at the bottom of the message:
HTML, TXT, Attachments....
Problem is the attachment here is a text file:
----==_mimepart_4d8f976d6359a_4f0d15a519e35138763f4
Date: Sun, 27 Mar 2011 13:00:45 -0700
Mime-Version: 1.0
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename=x00_129999.olk14message
Content-ID: <4d8f976d49c72_4f0d15a519e351387611f#railgun64.53331.mail>
Thanks
I know there is already an accepted answer, but switching the order of attachments[] and mail() didn't solve it for me. What is different about my situation is that I was trying to attach a text file attachment (.txt)
What works for me is setting the content_type and parts_order defaults for the mailer.
MyMailer < ActionMailer::Base
default :from => "Awesome App <support#example.com>",
:content_type => 'multipart/alternative',
:parts_order => [ "text/html", "text/enriched", "text/plain", "application/pdf" ]
def pdf_email(email, subject, pdfname, pdfpath)
attachments[pdfname] = File.read(pdfpath)
mail(:to => email, :subject => subject)
end
def txt_email(email, subject, filename, filebody)
attachments[filename] = filebody
mail(:to => email, :subject => subject)
end
end
If you are trying to send an email in Rails 3 with a plain text file (.txt), trying adding :content_type and parts_order to your defaults so that the text file does not appear above the message in your email.
I had the same problem, and in my case the solution was to swap the attachment and mail lines. First attach, then call mail.
Rails 3
WRONG
def pdf_email(email, subject, pdfname, pdfpath)
mail(:to => email, :subject => subject)
attachments[pdfname] = File.read(pdfpath)
end
GOOD
def pdf_email(email, subject, pdfname, pdfpath)
attachments[pdfname] = File.read(pdfpath)
mail(:to => email, :subject => subject)
end
this is rail 2.3 code (might be slightly different in rails3)
just move you text part before attachment
recipients to#domain.com
from me#domain.com
subject "some subject"
content_type "multipart/mixed"
part "text/plain" do |p|
p.body = render_message 'my_message' #this is template file
end
attachment "application/octet-stream" do |a|
a.body = File.read("some_file.jpg")
a.filename = 'name.jpg'
end

Resources