sending a form to two recipients in rails - ruby-on-rails

i have a rails model registrations that has the following fields
attr_accessible :address, :company, :name, :phone, :email
i have successfully been able to send a mail to the user via the email fielded in by the user and that works succesfully using action mailer
def create
#registration = Registration.new(params[:registration])
respond_to do |format|
if #registration.save
UserMailer.registration_confirmation(#registration).deliver
format.html { redirect_to root_path, notice:" Thanks! #{#registration.name}, Your registration have been
confirmed & your seat reserved" }
format.json { render :show, status: :created, location: #registration }
else
format.html { render action: "new" }
format.json { render json: #registration.errors, status: :unprocessable_entity }
end
end
end
and the registration mailer is as thus
def registration_confirmation(registration)
#registration = registration
#greeting = "Hi"
mail(to: #registration.email, subject: 'Welcome')
end
which works very well...
All i want to achieve is to be able to send a mail to another email address e.g (admin#gmail.com) stating that a user as registered and also showing the registration details ... thanks

I would generate a new mailer specifically for notifications that should be sent to the administrator.
rails g mailer AdminMailer registration_notice
You could then edit the AdminMailer registration_notice to be similar to your UserMailer, but with a different recipient:
def registration_notice(registration)
#registration = registration
mail(to: 'admin#gmail.com', subject: 'A new user has registered')
end
Put whatever registration details you would like to include into the views for registration_notice.html.erb (or text).
Then just add the call to the mailer in the create action of the controller, right after the call to the UserMailer:
def create
#registration = Registration.new(params[:registration])
respond_to do |format|
if #registration.save
UserMailer.registration_confirmation(#registration).deliver
AdminMailer.registration_notice(#registration).deliver
# etc
end
end
end
You'd probably also want to consider sending the mails in the background instead of making the user wait for the create request to finish, but that's beyond the scope of this question.

Related

NoMethodError (undefined method `deliver_invitation') devise invitable rails

Hello I have an app where a user is invited as an attendee
In the attendee controller, when the attendee is created the user is created but not sent an invite to the system
attendees_controller.rb
def create
#attendee = Attendee.new(attendee_params)
#user = User.invite!({email: "#{#attendee.email}"}, current_user) do |u|
u.skip_invitation = true
end
#attendee.user_id = #user.id
respond_to do |format|
if #attendee.save
format.html { redirect_to meeting_url(#attendee.meeting), notice: "Attendee was successfully created." }
format.json { render :show, status: :created, location: #attendee }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #attendee.errors, status: :unprocessable_entity }
end
end
end
in the same controller i then have a send_invite
def send_invite
#attendee = Attendee.find(params[:attendee_id])
User.where(id: #attendee.user_id).deliver_invitation
redirect_to meeting_url(#attendee.meeting)
end
when i hit it via a button I get
NoMethodError in AttendeesController#send_invite
undefined method `deliver_invitation' for #<ActiveRecord::Relation
[devise_invitable][1] clearly states
If you want to create the invitation but not send it, you can set skip_invitation to true.
user = User.invite!(email: 'new_user#example.com', name: 'John Doe') do |u|
u.skip_invitation = true
end
# => the record will be created, but the invitation email will not be sent
When generating the accept_user_invitation_url yourself, you must use the raw_invitation_token. This value is temporarily available when you invite a user and will be decrypted when received.
accept_user_invitation_url(invitation_token: user.raw_invitation_token)
When skip_invitation is used, you must also then set the invitation_sent_at field when the user is sent their token. Failure to do so will yield “Invalid invitation token” error when the user attempts to accept the invite. You can set the column, or call deliver_invitation to send the invitation and set the column:
user.deliver_invitation
What am I missing?
[1]: https://github.com/scambra/devise_invitable#send-an-invitation-
I guess .deliver_invitation is an instance method on the User Model. (through devise_invitable).
In that case you would probably want something like this:
User.where(id: #attendee.user_id).each do |user|
user.deliver_invitation
end
Assuming deliver_invitation is an instance method of the User model, you can modify your send_invite method like below:
def send_invite
#attendee = Attendee.find(params[:attendee_id])
user = User.find(#attendee.user_id)
user.deliver_invitation
redirect_to meeting_url(#attendee.meeting)
end

New method in a model or new service - which approach is better?

I am implementing a new app with following business process:
User fill in a registration form.
Once registration form is being saved, a new Training Company is created
User get an e-mail with a pdf with his registration form and unique url
User uses unique url to attach signed registration form Admin can accept or reject
What is the best approach to Training Company creation?
First solution: new service that creates a TrainingCompany
class TrainingCompanyService
def initialize(company_name)
#name = company_name
end
def create_new_training_company
TrainingCompany.new(company_name: #name).save
end
end
create action in RegistrationFormController:
def create
#registration_form = RegistrationForm.new(registration_form_params)
respond_to do |format|
if #registration_form.save
format.html { redirect_to #registration_form, notice: 'Registration form was successfully created.' }
TrainingCompanyService.new(#registration_form.company_name).create_new_training_company
RegistrationFormMailer.with(registration_form: #registration_form).after_registration_email.deliver_later
else
format.html { render :new }
end
end
end
Second solution: new method inside TrainingCompany model:
class RegistrationForm < ApplicationRecord
belongs_to :training_company, optional: true
has_one_attached :registration_form
has_secure_token :signed_form_upload_token
def create_new_training_company
TrainingCompany.new(company_name: self.company_name, registration_form_id: self.id).save
end
end
create action in RegistrationFormController:
def create
#registration_form = RegistrationForm.new(registration_form_params)
respond_to do |format|
if #registration_form.save && #registration_form.create_new_training_company
format.html { redirect_to #registration_form, notice: 'Registration form was successfully created.' }
RegistrationFormMailer.with(registration_form: #registration_form).after_registration_email.deliver_later
else
format.html { render :new }
end
end
end
Which solution would you choose and why? Personally i prefer the second one (new method inside the model)...

how to call actionmailer in rails admin controller?

I want to send a email to user after create something via rails admin.
I know I can call it in model callback but it's not considered as a good pratices
the best way is to put the actionmailer action after model save in the controller but I don't know how to do it in rails_admin controller
class UsersController < ApplicationController
# POST /users
# POST /users.json
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
# Tell the UserMailer to send a welcome email after save
UserMailer.welcome_email(#user).deliver_later
format.html { redirect_to(#user, notice: 'User was successfully created.') }
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
end
What you want to do is not easy on rails admin because you cannot modify the controllers nor do you have access to them without monkey patching them.
I actually made a fork of rails admin for this functionality checkout the commit with the changes:
https://github.com/aliada-mx/rails_admin/commit/6251554efd1d83cdb418f42683ee55a4e27c2474
Just touched two files
And example usage
class User
after_save :on_admin_updates
attr_accessor :edited_in_rails_admin
def on_admin_updates
return unless edited_in_rails_admin
self.edited_in_rails_admin = false
UserMailer.welcome_email(self.id)
end
end
A bit clunky i know, PR´s welcome.
Have you tried to include your Mailer in admin_controller?
include UserMailer
Then in your create action UserMailer.some_mailer_action.deliver_now

Send Mail to Multiple Recipient Without Recipients seeing the other people i am sending it to

I am trying to development this app that has a landing page where i can collect email addresses, log in as an admin and send mail to all the subscribed users, i am using Action mailer and my gmail account smtp configuration.
When i do send the mail, everyone gets cc'ed, and seeing as i am testing with my own google mail accounts, i can see the other people cc'ed.
Mailforsubcriber Controller
def create
#mailforsubscriber = Mailforsubscriber.new(mailforsubscriber_params)
respond_to do |format|
if #mailforsubscriber.save
RecipientMailer.newsletter(#mailforsubscriber).deliver_now
format.html { redirect_to #mailforsubscriber, notice: 'Mail for subscriber was successfully sent.' }
format.json { render :show, status: :created, location: #mailforsubscriber }
else
format.html { render :new }
format.json { render json: #mailforsubscriber.errors, status: :unprocessable_entity }
end
end
end
This is the recipient mailer code
class RecipientMailer < ApplicationMailer
require 'digest/sha2'
default from: "notification#example.com"
default to: Proc.new {Subscribeduser.pluck(:email) }
default "Message-ID" => "#{Digest::SHA2.hexdigest(Time.now.to_i.to_s)}#domain.com"
def newsletter(mailforsubscriber)
#mailforsubscriber = mailforsubscriber
mail(subject: "Newsletter")
end
end
how do i get around this?.
try use the CCO field, it's works like CC field, but don't show the other e-mails for everyone.
You can use something like this in your action mailer,
def newsletter(mailforsubscriber)
#mailforsubscriber = mailforsubscriber
mail(:to => #mailforsubscriber.email, :subject => "Newsletter")
end
Here i have called the method send_mail_persons and passed the recipients info as a parameter.This logic will make you loop across all the email ids and then send individually. If you want to send mail to all the users at once then you can use :bcc, say
mail(:to => "#mailforsubscriber.email" , :subject => "Example Subject",
:bcc => ["bcc1#abc.com", "bcc2#abc.com"])
If you are new to Rails, i would suggest to read this Action Mailer Basics. This covers end to end flow of a basic mailer template integration from controller to view.

Method to send multiple paperclip attachments through actionmailer in rails

So I need my mailer to send attachments that the user uploads in the form upon creation. I used cocoon and paperclip to attach multiple files in the form.
Here is my object_controller:
class RfqsController < ApplicationController
...
def create
#object= Rfq.new(rfq_params)
respond_to do |format|
if #object.save
Object_mailer.object_message(current_user, #object).deliver
format.html { redirect_to #object, notice: 'object was successfully created.' }
format.html { render :new }
end
end
end
...
This will send the email with multiple attachments
class ObjectMailer < ApplicationMailer
default from: "test#test.com"
def placeholder_message(user, rfq)
#user = user
object.object_attachments.each do |attachment|
attachments[attachment.attachment_file_file_name] = File.read(attachment.attachment_file.path)
end
mail to: user.email, subject: "test"
end
end

Resources