How can I use Rails mailer with dynamic values? - ruby-on-rails

I am new to Rails and struggling with how to implement dynamic values in my mailer.
The below code all works fine apart from the reply_to which I want a dynamic value but I don't know how to do this.
The params #name, #email, #message are captured on a form and I want the reply_to values to be the same as the params passed from #email.
So, essentially the point of this is someone can book an event and then it will email their details to the event manager who can then just press "reply" and it will reply back to the email the user filled out on the form.
class BookingMailer < ActionMailer::Base
default from: "notifications#example.com"
default reply_to: #email
def contact_mailer(name,email,message)
#name = name
#email = email
#message = message
mail(to: 'info#example.com', subject: 'Event Booking', reply_to: #email)
end
end
I looked on the API docs but they seem to reference users in a database when using dynamic values.
Any help is much appreciated, thanks!

You only set a default value if you wanted to use something for methods that DON'T have an option set (for example, you've set a default from:, so you don't need to set mail(from: "notifications#example.com"...) each time, it'll use the default if not set).
Providing your controller is passing the email address as the second argument then your code should work, although usually I'd pass a booking:
class BookingController < ApplicationController
def create
#booking = Booking.new(safe_params)
if #booking.save
BookingMailer.contact_mailer(#booking).deliver
else
# alarums!
end
end
end
Then extract the info you want from that in your mailer:
class BookingMailer < ActionMailer::Base
default from: 'blah#blah.com'
def contact_mailer(booking)
#booking = booking
mail(to: 'info#example.com', subject: 'Event booking', reply_to: #booking.email)
end
end
Ideally you should remove the line default reply_to: #email as it's trying to use a class level instance variable #email, instead of the instance variable #email that you intended. For examples on the differences between class variables, instance variables and class instance variables, see here: http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/

Related

access "self" from view after sending mail (ruby on rails)

After a user signs up (Devise RegistrationController), I want to send them a welcome email.
Inside my User model, I created a function:
def send_welcome_email
UserMailer.welcome(self).deliver
end
Then I've added after_create :send_welcome_email
Inside the email view, I need to access variables.
<p><span><strong>Hi <%= self.name %>,</strong></span></p>
Returns an error:
undefined method `name' for #<#<Class:0x00007fa7d18e13b0>:0x00007fa7e4025358>
It makes sense that this would result in the error above, but I'm not sure how I can access variables from the model (that was just created).
I was following this asnwer: https://stackoverflow.com/a/17480095/9200273
Welcome method:
def welcome(user)
mail(
to: user.email,
subject: 'Welcome to Site!',
from: "support#site.com"
)
end
You can pass objects to the Mailer class using the with method like this:
UserMailer.with(user: self).welcome.deliver
Inside the UserMailer class:
def welcome_email
#user = params[:user]
...
end
In the view:
<%= #user.name %>
Reference: https://guides.rubyonrails.org/action_mailer_basics.html

is it possible to use an instance or variable in the subject of rails mailer and how please :)

I would like to use an instance or variable like below in the mailer subject.
So I would like to get the user name or some other user detail in the subject, I tried several thing but I receive an error every time. I can't find documentation about this either.
mail(:to => "test#gmail, :subject => "current_user.name") or "<%= current_user.name %>"
class PositionMailer < ActionMailer::Base
default from: "test#gmail.com"
layout 'mailer'
def general_message(position, barge_name)
#position = position
#barge_name = barge_name
mail(:to => "1234#gmail.com, :subject => "#{barge_name}")
end
end
controller
def create
#position = Position.new(position_params)
if #position.save!
redirect_to #position
PositionMailer.general_message(#position, #barge_name).deliver
To pass a variable inside quotes you need to do it like this "#{variable.value}
:subject => "#{current_user.name}"
should do it if it has access to current_user
You will have to pass current_user to the mailer along with the position value.
So wherever you are calling that from add current_user, probably looks something like this.
PositionMailer.general_message(position, current_user).deliver

Issues Looping through an array in Active Mailer

I am trying to implement a feature which allows user to send one email to multiple recipients. I split the recipient email params by calling the .split method which turns it into an array. Then I loop through the array with the each method which should apply the mail method to each element in the array. The controller and mailer code is given below.
controller code
def create
#scoreboard = Scoreboard.find(params[:scoreboard_id])
#invitation = #scoreboard.sent_invitations.build(invitation_params)
if #invitation.save
UserMailer.registered_invitation_email(#scoreboard, #invitation).deliver_now
flash[:success] = "Invitation sent successfully"
redirect_to new_scoreboard_invitation_path
else
render 'new'
end
end
end
mailer code
def registered_invitation_email(scoreboard, invitation)
#scoreboard = scoreboard
#invitation = invitation
split_email = #invitation.recipient_email.split
split_email.each do |email|
mail(to: email, subject: "View scoreboard")
end
end
The problem is that it only sends the email to the last element in the array. For example, if the user types in "joe#example.com Mike#example.com" in the form it will only send an email to the last element in an array. In this case, Mike#exapmle.com. I am not sure why that is. I think I am looping through it correctly. I am not sure what's causing the problem. I am not sure if its the loop or maybe loops don't work in active mailer. Not exactly sure. Any help would be appreciated. Thanks!!
Try something like this
Create a model with fields
field :mail_to
field :subject
create a method in the same model
def deliver
UserMailer.send_invitation_mail(self).deliver
end
Mailer
def send_invitation_mail(email)
mail(to: email.mail_to, subject: email.subject)
email.destroy
end
Controller
def create
user_emails.each do |email|
email = Email.new(:mail_to => "xxx#yyy.com",:subject => "View Scoreboard") # Email is the model name.
email.deliver
sleep(1)
end
end
This way u can also log and also deliver all mails together in the model and also do various manipulations on the email.

Is it possible to replace default from: with an email from database in Rails Action Mailer?

I am trying to pass on an email from a user to the default from: field so that it looks like it's coming directly from them. Here is what I have right now. Is there any way of bringing in a dynamic variable into the default from field?
class IntroMailer < ActionMailer::Base
default from: "Me#gmail.com"
def intro_email(intro)
#intro = intro
mail(to: #intro.person1_email, subject: 'Testing Intro Email')
end
end
You can override this in the Mailer action's mail method:
class IntroMailer < ActionMailer::Base
default from: "Me#gmail.com"
def intro_email(intro, current_user)
mail(to: intro.person1_email, subject: 'Testing Intro Email', from: current_user.email)
end
end
but a WARNING. Email clients, like Google, are pretty smart at detecting spam. If they see that a specific SMTP server is sending out emails with lots of different 'from' attributes, your spam rating will go up and your emails will be filtered out by spam filters. To get around this, choose one or two default from emails (e.g. support#mywebsite.com & jobs#mywebsite.com) that fit the email's type, and then add a dynamic reply_to attribute instead.
class IntroMailer < ActionMailer::Base
default from: "ourteam#oursite.com"
def intro_email(intro, current_user)
mail(to: intro.person1_email, subject: 'Testing Intro Email', reply_to: full_from(current_user))
end
private
def full_from(user)
address = Mail::Address.new user.email
address.display_name = user.full_name
address.format
end
end
Actually not, it doesn't work at all in Rails 5.XX

Displaying Action Mailer variable in view returns "nil"

I am trying to let a user submit a form that sends an email message to another user. Everything is working fine, except I am trying to store the body of the email in a variable to display in the view for the mailer and am getting 'nil'. I set up a user_mailer.rb:
class UserMailer < ActionMailer::Base
default :from => "myemail#gmail.com"
def message_user(user, recipient, subject, body)
#user = user
#recipient = recipient
#body = "#{body}"
mail(:to => "#{recipient.name} <#{recipient.email}>", :subject => "Reelify message: #{subject}" )
end
end
and here is my messages_controller.rb :
def new
#user = current_user
if !params[:receiver].blank? and !params[:subject].blank? and !params[:body].blank?
#recipient = User.find_by_name(params[:receiver])
UserMailer.message_user(#user, #recipient, params[:subject], params[:body]).deliver
flash[:notice] = "This flash means it should work.. #{#user.name} #{#recipient.name}"
end
end
When I call #body in the view, it is blank (#body.inspect) results in 'nil'. However, if I do something like: #{body} in place of the subject line, the text will render fine.
Anyone have any clue whats going on?
how about # user, is it displayed correctly? May be #body is used by rails, try rename.

Resources