Thanks for reading this post guys. Rails newbie here with what I'm pretty sure is a fundamental error.
I have a users table with a column 'added_by' that shows which user added them to the database.
So in this example, Melissa (id:2) was added by Thomas (id:1).
This is my Actionmailer notification_mail.rb, that fires emails when tickets are created:
class NotificationMailer < ActionMailer::Base
add_template_helper HtmlTextHelper
def new_ticket(ticket, user)
unless user.locale.blank?
#locale = user.locale
else
#locale = Rails.configuration.i18n.default_locale
end
title = I18n::translate(:new_ticket, locale: #locale) + ': ' + ticket.subject.to_s
add_attachments(ticket)
unless ticket.message_id.blank?
headers['Message-ID'] = "<#{ticket.message_id}>"
end
#ticket = ticket
#user = user
assoc = User.find_by_id(user.added_by)
mail(to: user.email, subject: title, from: ticket.reply_from_address) #sends email to ticket creator
mail(to: assoc.email, subject: title, from: ticket.reply_from_address) #sends email to user who added ticket creator
end
It should send an email to:
The ticket creator.
The user who added the ticket creator.
But this is the error I get:
undefined method `email' for nil:NilClass
Which comes from this line:
mail(to: assoc.email, subject: title, from: ticket.reply_from_address)
I'm pretty sure it's to do with me not including something in this file, but I simply can't figure it out despite reading other questions and ruby documentation.
Can someone help?
Thanks guys.
If added_by is not present for an user in the database (which is the case for Thomas in your given example) then assoc = User.find_by_id(user.added_by) won't find the assoc user record and assoc will be nil. So, if you call assoc.email it will fail with this message:
undefined method `email' for nil:NilClass
Alternatively, you can do:
assoc.try(:email)
Or, you can check first if assoc is present, only then you send them email:
if assoc && assoc.email
#sends email to user who added ticket creator
mail(to: assoc.email, subject: title, from: ticket.reply_from_address)
end
Related
I want to give different sender email credentials according to the user of application in rails which will be fetched from database.
If you're using ActionMailer, you can to set 'from':
fetch_sender = Object.select(:email, :name).find(id)
mail(from: "#{fetch_sender.name} <#{fetch_sender.email}>", to: 'Receiver <example#receiver.com>', subject: 'Something')
Example for ActionMailer class:
app/mailers/custom_mailer.rb
class CustomMailer < ApplicationMailer
def custom(sender, receiver)
mail(from: "#{sender.name} <#{sender.email}>", to: "#{receiver.name} <#{receiver.email}>", subject: 'Something')
end
end
For sending
CustomMailer.custom(sender, receiver).deliver
P.s. If you have sidekiq or something else, yo may use deliver_now or deliver_later
I would like to send an email to a user once the status of their pdform is updated. I already have some stuff written out on how I want this done.
In my pdform.rb model
after_update :sendemail
def sendemail
if status_changed?
end
end
I already have emails being sent out when the user creates a new form, however, I am not sure how to send an email in the model.
The controller has this mailer function that works correctly. How could I send this in this model?
NewPdform.notify_user(current_user, #pdform).deliver
Any help would be greatly appreciated. Still getting the hang of ActiveRecord.
Update:
In my pdforms_controller update method I have added the following variable.
update_user = #pdform.user
I added an attr_accessor in pdform.rb (the model)
attr_accessor :update_user
after_update :sendemail
def sendemail
NewPdform.notify_update(update_user).deliver
end
And in my mailer
def notify_update(user)
#user = user
mail(to: #user.email, subject: "some change occured")
end
I solved my own issue after using my brain more extensively.
In the call to the mailer function instead of passing the parameter of pdform, which is the name of the class anyways, just pass self.
def sendemail
NewPdform.notify_update(self).deliver
end
I've got an app where users submit weeks which can be approved or denied, and in my weeks controller I have the following lines meant to iterate over the selected weeks, find their corresponding users and send each user an email:
elsif params[:commit] == "Reject selected weeks"
user_week = Week.where(id: params[:weeks_ids])
user_week.update_all(approved?: false)
# fetch the set of user_emails by converting the user_weeks to user_ids
users = User.find(user_week.pluck(:user_id))
users.each do |user|
#iterate over the users and send each one an email
UserMailer.send_rejection(user).deliver
end
flash[:info] = "Selected weeks were Rejected."
end
redirect_to weeks_path
When I attempt to reject a week, I receive the following error message:
undefined method `send_rejection' for UserMailer:Class
I'm adding on to pre-existing code and have little knowledge of MVC, so the only issues I can think of would be with placing the mailer method in the wrong file or sending an incorrect type of arg to the mailer method.
Here is "send_rejection", the mailer contained in my user model.
def send_rejection(user)
UserMailer.reject_timesheet(user).deliver_now
end
The corresponding method in my user_mailer.rb file:
def reject_timesheet(user)
#greeting = "Hi"
mail to: user.email, subject: "Rejected Timesheet"
end
New to rails and not sure where I'm going wrong.
This is not a problem of MVC, one question I'd probably ask is why are you not calling the reject_timesheet directly instead of send_rejection.
You're getting the error because as you said the method is defined in the user model, so in order to call the method, you'd need to do:
user.send_rejection
In which case I doubt you'd be needing to pass a user argument to the send_rejection, as you could just do:
class User
def send_rejection
UserMailer.reject_timesheet(self).deliver_now
end
end
then in your controller:
...
users.each do |user|
#iterate over the users and send each one an email
user.send_rejection
end
...
I believe you could also clean up your codebase a bit and possibly refactor some logic, but basically this approach should resolve your errors.
Let me know if that helps
I am using admin mailer in my Rails 4 app.
I have two emails to send out upon registration. One is to me and the other is to the user. They are supposed to send from different email addresses, each of which is specified in the from field in the mailer method (as set out below). The problem is they are both being sent from the email address specified as the sender in the first method.
My mailer methods are:
def new_user_waiting_for_approval(user)
#user = user
mail(to: "aa#gmail.com", from: "bb#gmail.com",
subject: "Registration Request #{user.first_name} #{user.last_name} <#{user.email}>")
end
def new_user_waiting_for_access(user)
#user = user
mail(to: user.email, from: "cc#gmail.com", subject: "Welcome, #{user.first_name}")
end
Inside my Admin_Mailer class, I have a default 'from:' email address above the method which is specified as the sender in the first of the above methods. This might be overriding the from specified in the method itself.
Does anyone know how to specify different senders in separate methods so that my emails send from the appropriate email address?
Thank you
If you couldn't figure it out by changing the configs you can use the code given below.
Add this code snippet to your code base.
class Emailer < ActionMailer::Base
def activation_instructions(recipients_emails, sender = nil, mail_subject = nil, text = "")
subject mail_subject || "Default subject"
recipients recipients_emails
from sender || "default_mail_id#abc.com"
sent_on Time.now
content_type "text/html"
body text
end
end
And you can send the mail by calling the above defined method as follows.
Emailer.deliver_activation_instructions("recient#abc.com", "sender#abc.com", "Subject", "content")
I have this in my user_mailer.rb
class UserMailer < ActionMailer::Base
default from: ["no-reply##{CONFIG[:domain]}"]
def password_reset(user, portal_name)
#user = user
mail to: #user.email, subject: t('emails.password_reset.subject')
end
end
I have this in my yml translation file:
emails:
password_reset:
subject: You've requested to reset your password
There are no characters at the end of the translation string, however when the email is sent the subject appears like this in the email: "You've requested to reset your password=0A"
I've tried searching for an answer and I found Rails used to have an ActionMailer::Quoting.quoted_printable method, but it seems this no longer exists in rails 4.
Where is the "=0A" coming from? Any built-in solution to this in rails?
I managed to solve the problem by adding a chomp at the end:
mail to: user.email, subject: t('emails.password_reset.subject').chomp
It seems a newline was being introduced somewhere!
I also encountered this problem when using the 'X-SMTPAPI' header(SendCloud Mail Service).This is because Mail gem will handle the headers:
def encode_crlf(value)
value.gsub!(CR, CR_ENCODED)
value.gsub!(LF, LF_ENCODED)
value
end
When I tried using Mail gem only, it worked. I think this is because the charset is different with Rails' default setting. I solved the issue like this:
headers["X-SMTPAPI"] = Base64.encode64(JSON.dump({"to" => emails, "sub" => {"%name%" => names}})).gsub!(/\n/,'')