ActionMailer help, paste email from session! - ruby-on-rails

Notifier.rb
class Notifier < ActionMailer::Base
def inquiry_notification(inquiry)
recipients inquiry.respondent.email
from "#{#laz.email}"
subject "Survey"
content_type "text/html"
end
end
Part of Controller.rb
...
#laz = User.find(:all)
respondents.each do |r|
inquiry = Inquiry.create(:question_id => #question.id, :respondent_id => r.id, :is_answered => 0)
Notifier.deliver_inquiry_notification(inquiry)
end
....
I need to paste into "FROM" (notifier.rb) email that user has.
For example: session[:user].email <- paste this , because i work with sessions and i have many users (admins and auditors).

Why dont you just add additional parameter to your inquiry_notification method like this:
def inquiry_notification(inquiry, from_email)
recipients inquiry.respondent.email
from from_email
subject "Survey"
content_type "text/html"
end
If you dont want to do so, you can use for example Thread.current:
in controller
Thread.current[:email] = 'test#email.com'
in Notifier
def inquiry_notification(inquiry)
recipients inquiry.respondent.email
from Thread.current[:email]
subject "Survey"
content_type "text/html"
end

Related

How to send mail for multiple models in rails

I am new to rails. I am having problem in mail sending to multiple models. Our project contains parent,teacher and student models.each module having number of users(student,parent,teacher). And also I am having three check box.that is student,teacher,parent.when I click student and teacher.the mail should be sent to all teachers and all students.
If I want send a mail to teacher and also student means ,the problem behind this, mail was sending only to teacher not student. how to solve this problem.and I included my coding.
Controller
def send_news_letter
if params[:announcement].present?
#announcement = Announcement.find(params[:announcement].keys).first
end
if params[:students].present? and params[:teachers].present?
#student = Student.pluck(:email)
#teacher = Teacher.pluck(:email)
UserMailer.send_multiple_email(#student,#teacher,#announcement).deliver
redirect_to announcements_url, :notice => "Newsletter Delivered Successfully" a
end
end
Usermailer.rb
class UserMailer < ActionMailer::Base
default to: Proc.new {Teacher.pluck(:email)},
to: Proc.new {Student.pluck(:email)},
from: "from#example.com"
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.user_mailer.password_reset.subject
#
def password_reset(user)
#user = user
mail :to => user.email, :subject => "Password Reset"
end
def send_multiple_email(user,employee,announcement)
#user = user
#employee = employee
#announcement = announcement
mail :subject => "Deliver"
end
end
Please help me.Thanks in advance.
First, in your controller I would store all addresses in one array:
#emails = []
if params[:students].present?
#emails += Student.pluck(:email)
end
if params[:teachers].present?
#emails += Teacher.pluck(:email)
end
if params[:parents].present?
#emails += Parent.pluck(:email)
end
UserMailer.send_multiple_email(#emails,#announcement).deliver
And then in your mailer change to this:
def send_multiple_email(emails,announcement)
#announcement = announcement
emails.each do | address |
mail :to => address, :subject => "Deliver"
end
end
Please note, that if you're referencing your models in the mailer template (such as "Hi <%= #user.name %>!") then you need to load the whole model object. Now you're just using pluck to get a list of all the addresses you want to send to. To get the whole model, change pluck(:email) to all in your controller and change your mailer to reference the attributes in that model instead. This also means your three models need to have the same attribute names (at least the ones you intend to use in the mailer).
Hope it makes sense.

Override mailer in devise_invitable?

I would like the invitations for my app to come from the inviter instead of a system email address. How can I override the config.mailer_sender from devise.rb?
I have this in my mailer and have confirmed that it is getting called, but it does not override the :from. Note: it is a private method, I tried it as a public method with no effect.
private
def headers_for(action)
if action == :invitation_instructions
headers = {
:subject => "#{resource.invited_by.full_name} has invited you to join iTourSmart",
:from => resource.invited_by.email,
:to => resource.email,
:template_path => template_paths
}
else
headers = {
:from => mailer_sender(devise_mapping),
:to => resource.email,
:template_path => template_paths
}
end
if resource.respond_to?(:headers_for)
headers.merge!(resource.headers_for(action))
end
unless headers.key?(:reply_to)
headers[:reply_to] = headers[:from]
end
headers
end
The better solution without any hacks/monkey patches will be:
for example, in your model:
def invite_and_notificate_member user_email
member = User.invite!({ email: user_email }, self.account_user) do |u|
u.skip_invitation = true
end
notificate_by_invitation!(member)
end
def notificate_by_invitation! member
UserMailer.invited_user_instructions(member, self.account_user, self.name).deliver
end
In the mailer:
def invited_user_instructions(user, current_user, sa)
#user = user
#current_user = current_user
#sa = sa
mail(to: user.email, subject: "#{current_user.name} (#{current_user.email}) has invited you to the #{sa} account ")
end
So you can put any subject/data in the body of the mail.
Good luck!
Look at my answer to a similar question, it might help.
Edit: so it seems that you need to define a public headers_for method in your resource class.
Solution: Put some version of this method in User.rb, make sure it's public.
def headers_for(action)
action_string = action.to_s
case action_string
when "invitation" || "invitation_instructions"
{:from => 'foo#bar.com'}
else
{}
end
end
You have to return a hash in because Devise::Mailer will try to merge the hash values.
Take a look at devise_invitable wiki.
class User < ActiveRecord::Base
#... regular implementation ...
# This method is called interally during the Devise invitation process. We are
# using it to allow for a custom email subject. These options get merged into the
# internal devise_invitable options. Tread Carefully.
#
def headers_for(action)
return {} unless invited_by && action == :invitation_instructions
{ subject: "#{invited_by.full_name} has given you access to their account" }
end
end

Rails - ActionMailer - How to send an attachment that you create?

In rails3 w ActionMailer, I want to send a .txt file attachment. The challenge is this txt file does not exist but rather I want to create the txt file given a large block of text that I have.
Possible? Ideas? Thanks
It's described for files in the API documentation of ActionMailer::Base
class ApplicationMailer < ActionMailer::Base
def welcome(recipient)
attachments['free_book.pdf'] = File.read('path/to/file.pdf')
mail(:to => recipient, :subject => "New account information")
end
end
But that doesn't have to be a File, it can be a string too. So you could do something like (I'm also using the longer Hash-based form where you can specify your own mimetype too, you can find documentation for this in ActionMailer::Base#attachments):
class ApplicationMailer < ActionMailer::Base
def welcome(recipient)
attachments['filename.jpg'] = {:mime_type => 'application/mymimetype',
:content => some_string }
mail(:to => recipient, :subject => "New account information")
end
end
First the method to send email
class ApplicationMailer < ActionMailer::Base
def welcome(user, filename, path)
attachments[filename] = File.read(path)
mail(:to => user.email, :subject => "New account information")
end
end
Call the method with the params
UserMailer.welcome(user, filename, path).deliver

How do I attach a prawnto-rendered .pdf to an email in Rails 2.3.5?

My application creates a .pdf file when it is rendered by passing it to the URL (for example, domain.com/letter/2.pdf)
It doesn't get saved anywhere.
How can I make that actual pdf an attachment in an outbound email.
Here is my mailer:
def campaign_email(contact,email)
subject email.subject
recipients contact.email
from 'Me <me#me.com>'
sent_on Date.today
attachment = File.read("http://localhost:3000/contact_letters/#{attachment.id}.pdf")
attachment "application/pdf" do |a|
a.body = attachment
a.filename = "Othersheet.pdf"
end
end
This is the controller that creates/renders the PDF:
def create
#contact_letter = ContactLetter.new(params[:contact_letter])
#contact = Contact.find_by_id(#contact_letter.contact_id)
#letter = Letter.find_by_id(#contact_letter.letter_id)
if #contact_letter.save
flash[:notice] = "Successfully created contact letter."
#redirect_to contact_path(#contact_letter.contact_id)
redirect_to contact_letter_path(#contact_letter, :format => 'pdf')
else
render :action => 'new'
end
end
NOTE: I hardcoded localhost:3000/ how can I substitute that with a variable so that on dev it is localhost:3000 and on production is it the correct domain? Is there a way to include routing in this?)
ERROR: I get an
Invalid argument -
http://localhost:3000/contact_letters/9.pdf
Here's an example for rails 2
class ApplicationMailer < ActionMailer::Base
# attachments
def signup_notification(recipient, letter)
recipients recipient.email_address_with_name
subject "New account information"
from "system#example.com"
attachment :content_type => "image/jpeg",
:body => File.read("an-image.jpg")
attachment "application/pdf" do |a|
a.body = letter
end
end
end
in your view or wherever your calling your method:
ApplicationMailer.deliver_signup_notification(letter)
one quick an easy solution would be fetch the url content using net/http and open-uri, to get the attachment
attachments['free_book.pdf'] = open("http://#{request.host}/letter/#{id}.pdf")
eg:
def campaign_email(contact,email)
subject email.subject
recipients contact.email
attachments['free_book.pdf'] = open("http://#{request.host}/letter/#{id}.pdf")
from 'Me <me#me.com>'
sent_on Date.today
body :email => email
end
or, call the PDF generation inside your mailer controller action
I got it to work by passing the pdf object directly into the campaign_email method and then assigning an attachment.

reuse action mailer template

How do I reuse the same action mailer template for multiple mailer "actions"?
In ActionController, you can do
...
render :action => 'another_action'
I'd imagine the same thing can be done in ActionMailer, but I couldn't seem to find the right method. If it's relevant, I'm on Rails 2.3.2.
Thanks!
You're looking for render_message, there is a good example in the API Docs Multipart Message section - pasted below.
class ApplicationMailer < ActionMailer::Base
def signup_notification(recipient)
recipients recipient.email_address_with_name
subject "New account information"
from "system#example.com"
content_type "multipart/alternative"
part :content_type => "text/html",
:body => render_message("signup-as-html", :account => recipient)
part "text/plain" do |p|
p.body = render_message("signup-as-plain", :account => recipient)
p.transfer_encoding = "base64"
end
end
end

Resources