I'm trying to figure out how to setup a mailer class in my Rails 4 app.
I have made a mailer called admin_notes. I want to use it to send emails to the internal team when certain actions are taken across the site.
In my mailer/admin_note.rb, I have:
class AdminNote < ApplicationMailer
def unknown_organisation(organisation_request, user_full_name, name)
#organisation_request =
#user_full_name =
#organisation_request.name =
# #greeting = "Hi"
mail( to: "test#testerongmail.com",from: "test#testerongmail.com", subject: "A new organisation")
end
end
I have an organisation_requests model. It has:
class OrganisationRequest < ActiveRecord::Base
belongs_to :profile
delegate :user_full_name, to: :profile, prefix: false, allow_nil: true
The organisation request table has an attribute called :name in it.
When a new organisation request is created, I want to send an admin note to the internal team, alerting someone to start a process.
I'm struggling to figure out how I define the three variables in the mailer method.
I plan to add the send email call to the create action in the organisation requests controller.
How can I set these variables?
Form to create an organisation request is:
<%= simple_form_for(#organisation_request) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :organisation_id, collection: #all_organisations << ['other', nil] %>
</div>
<div class="form-inputs">
<%= f.input :name %>
</div>
<div class="form-actions">
<%= f.button :submit, "Create", :class => 'formsubmit' %>
</div>
<% end %>
NEW ATTEMPT:
I have a create action in my organisation controller, I added this service class request for an email:
def create
#organisation_request = OrganisationRequest.new(organisation_request_params)
#organisation_request.profile_id = current_user.profile.id
if #organisation_request.save
NewOrgRequestService.send_unknown_organisation_requested_flag(organisation_request)
return redirect_to(profile_path(current_user.profile),
flash[:alert] => 'Your request is being processed.')
else
# Failure scenario below
#all_organisations = Organisation.select(:title, :id).map { |org| [org.title, org.id] }
render :new
end
end
I then have a services/organisations requests/NewOrgRequestService.rb
class OrganisationRequest < ActiveRecord::Base
class NewOrgRequestService
attr_accessor :organisation_request
def self.send_unknown_organisation_requested_flag(organisation_request)
if #organisation_request.name.present?
AdminNote.unknown_organisation_requested(organisation_request, user_full_name, name).deliver_later
end
end
end
end
The AdminNote mailer has:
class AdminNote < ApplicationMailer
layout 'transactional_mailer'
def unknown_organisation_requested(organisation_request, user_full_name, name)
#organisation_request = #organisation_request
#user_full_name = #organisation_request.user_full_name
#name = organisation_request.name
# #greeting = "Hi"
mail
to: "test#testerongmail.com",from: "test#testerongmail.com", subject: "A new organisation"
end
end
This doesnt work, but I'm wondering if Im on the right track? Im not sure if the create action in the controller needs to have some kind of reference to the services/organisation_requests/ path that gets to the file??
I think I may have made a bigger mess than I started with - but I'm out of ideas for things to try next.
This may help you.
In your mailer method
def unknown_organisation(org,user)
#org = org
#user = user
mail(to: "test#testerongmail.com",from: "test#testerongmail.com", subject: "A new organisation")
end
In your controller method after saving organization_request and this is how you set your variable. You can pass variable you want.
AdminNote.unknown_organization(#organization_request, current_user).deliver_now
In your mailer template access passed value as you do in action view. And this is how you use your variable.
<%= #org.name %>
<%= #org.full_name %>
Hope this helps
If you want to queue message or send later you can use ActiveJob to send mails in the background.
For more, see http://guides.rubyonrails.org/active_job_basics.html
I know I am super late but here I go.
I understand that you are trying to send in some parameters (values) to mailer so that you can use it while sending an email.
To do so you just need to define a mailer method that accepts some parameters. What you have done is right in your AdminNote Mailer unknown_organization method.
Let's get to your NEW ATTEMPT.
Everything you have done there seems about right except you are passing an undefined variable organization_request. You have created an instance variable #organization_request but you are passing something that is not defined. Here
NewOrgRequestService.send_unknown_organisation_requested_flag(organisation_request)
That is your first problem. This can be improved as:
Your Organizations#create
def create
#organisation_request = OrganisationRequest.new(organisation_request_params)
#organisation_request.profile_id = current_user.profile.id
if #organisation_request.save
#organisation_request.send_unknown_organisation_requested_flag
redirect_to(profile_path(current_user.profile),
flash[:alert] => 'Your request is being processed.')
else
# Failure scenario below
#all_organisations = Organisation.select(:title, :id).map { |org| [org.title, org.id] }
render :new
end
end
And your model can be as follows:
class OrganisationRequest < ActiveRecord::Base
def send_unknown_organisation_requested_flag
if self.name.present?
AdminNote.unknown_organisation_requested(self).deliver_later
end
end
end
I don't know why you are defining a class inside your model class.
Your Mailer should look like below:
class AdminNote < ApplicationMailer
layout 'transactional_mailer'
def unknown_organisation_requested(organisation_request)
#organisation_request = organisation_request
#user_full_name = #organisation_request.user_full_name
#name = organisation_request.name
# #greeting = "Hi"
mail
to: "test#testerongmail.com",from: "test#testerongmail.com", subject: "A new organisation"
end
end
There are a lot of typos and method implementation errors here.
Related
I want to build feedback form to send it body to some e-mail box. Each form belongs to many pages (but page has only one form), has one title and body and can have one e-mail. Now it works like this:
app/views/shared/_custom_form.html.slim
= form_for #feedback, method: :post, url: feedback_path, remote: true do |f|
fieldset.b-form-field style='display:none'
= f.text_field :email, value: #feedback.email
fieldset.b-form-field
= f.label :title, "Title"
= f.text_field :title, value: #feedback.title
fieldset.b-form-field
= f.text_field :body, value: #feedback.body
fieldset.b-form-field
= f.submit "Send"
app/controllers/pages_controller.rb
class PagesController < FrontendController
def show
#feedback = Feedback.new
end
end
app/controllers/feedback_controller.rb
class FeedbackController < FrontendController
def new
#feedback = Feedback.new
end
def create
#feedback = Feedback.new(feedback_params)
respond_to do |format|
if #feedback.valid?
eml_sett =
if feedback_params[:email]
feedback_params[:email]
else
setting_value(:main_email)
end
if eml_sett.present?
FeedbackMailer.feedback_message(#feedback, eml_sett).deliver
end
end
end
end
def feedback_params
params.require(:feedback).permit(:title, :body, :email)
end
So, #feedback is created in my view, and then it goes from page controller to feedback_controller where it will be sended to form owner or to default email address. It work perfectly (i know, it is better to use hidden_field, but it is raw project), but i want to totally hide e-mail address from html code. So, i tried in my view:
= form_for #feedback(email: 'test#test.com')...
= form_for #feedback...
- #feedback.email = 'test#test.com'
= form_for Feedback.new(email: 'test#test.com')
But nothing helped. If I run '- puts #feedback.email' in my view, it returns email value, but in feedback controller 'puts feedback_params[:email]' returns nothing and form is sended to default email box. What am I doing wrong? Where is the mistake? Using Rails 4.1.8/Ruby 2.2.0.
I am guessing that your pages#show action displays a generic page with a 'sign up for newsletter' type of form. However, since you want to capture more data, right now you want to direct the user flow to a feedback page, which is served at feedback#new.
If so, what you can do is make the pages#show form submit a GET request on feedback#new, something like this:
= form_for :feedback, url: new_feedback_path, method: :get do |f|
= f.input :email
= f.submit
In your feedback#new action, you can do something like this:
def new
#feedback = Feedback.new(feedback_params)
end
If you use require(:feedback) in your strong params, then this will be a problem if you want to allow access to the new action without first supplying an email, but I'll leave that for you to decide if you want to support that.
What you are saying about using hidden fields, well you can't avoid it since it is user input. So whether or not you enable it as an editable input field, or keep it hidden, the user can supply any value whatsoever on the first page, which is pages#show.
If what you need is to hide the email, then yes you don't need a form field anywhere. This is what you do in your controller:
def create
#feedback = Feedback.new(feedback_params)
FeedbackMailer.feedback_message(#feedback).deliver
end
And in your mailer:
class FeedbackMailer < ApplicationMailer
def feedback_notification(feedback)
#feedback = feedback
mail(to: admin_email, from: #feedback.email, subject: #feedback.title)
end
private
def admin_email
ENV['ADMIN_EMAIL']
end
end
try this:
form_for #feedback... do |f|
= f.hidden_field :email
When I write a message and when pressing the send option,
I want to store student_id, coach_id and message to the database. student_id and coach_id are being saved, but the message field is not being saved. It shows null in the database. How do I fix this?
Any help is appreciated.
Controller file:
class CourseQueriesController <ApplicationController
def index
#course_query = CourseQuery.new
end
def create
# #course_query = CourseQuery.new(course_query_params)
#course_query = CourseQuery.where(student_id: current_student.id, coach_id: "2", message: params[:message]).first_or_create
if #course_query.save
redirect_to course_queries_path, notice: 'Query was successfully send.'
else
render :new
end
end
private
def set_course_query
#course_query = CourseQuery.find(params[:id])
end
# def course_query_params
# params[:course_query].permit(:message)
# end
end
model/course_query.rb:
class CourseQuery < ActiveRecord::Base
belongs_to :student
belongs_to :coach
end
view/course_query/index.html.erb:
<%= simple_form_for (#course_query) do |f| %>
<%= f.button :submit , "Send or press enter"%>
<%= f.input :message %>
<% end %>
database /course_queries:
It seems you didn't permit :course_query.
Try to permit your params the following way:
def course_query_params
params.require(:course_query).permit(:message)
end
But according to the 2nd way you pass params (params[:message]) I think you have a bit different params structure. So try another one:
def course_query_params
params.permit(:message)
end
When you look into the params generated in the log, you will see that the message inside the course_query hash, so params[:message] should be params[:course_query][:message]
#course_query = CourseQuery.where(student_id: current_student.id, coach_id: "2", message: params[:course_query][:message]).first_or_create
I've created a single page landing site which contains a simple waitlist form that dumps the info into a google doc (trying to keep it low tech for now, since an app will be built on top of this as well).
I'm trying to send the people who submit their email address for the waiting list a confirmation email. Can I pass the email address to a mailer without creating a model/controller and use of a db?
I've done this before by creating a model/controller (see below code) and use of a db (postgreSQL / Heroku), but it seems messy for such a simple task.
Here's my setup in the past, looking to get rid of the model/controller and pass the email address (w/ .downcase transformation) to the mailer directly.
models/waitlist.rb
class WaitList < ActiveRecord::Base
before_save {self.email = email.downcase}
attr_accessible :email
validates :email, :presence => true, format: { with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i }
end
controllers/waitlist_controller.rb
class WaitlistsController < ApplicationController
def create
#waitlist = Waitlist.new(params[:waitlist])
if #waitlist.save
# Tell the ProspectMailer to send an email to us
WaitlistMailer.waitlist_email(#waitlist).deliver
end
end
private
end
mailer/waitlist.rb
class Waitlist < ActionMailer::Base
default from: "hello#domain.com"
def waitlist_email(waitlist)
#waitlist = waitlist
mail( :to => #waitlist.email,
:subject => 'Thanks for signing up!' )
end
end
views/waitlist/waitlist_email.html.erb
Email text (possibly HTML) for the body of the email sent via the mailer
Thanks for the help!
Your controller should tell the Mailer to send the email.
In your controller create action, why not just pass the email param to your mailer?
app/controllers/wait_lists_controller.rb
class WaitListsController < ApplicationController
def create
send_wait_list_email(params[:wait_list][:email])
end
private
def send_wait_list_email(email)
WaitListMailer.wait_list_email(email).deliver
end
end
app/mailers/wait_list_mailer.rb
class WaitListMailer < ActionMailer::Base
def wait_list_email(email)
mail(to: email, subject: "Thanks for signing up!")
end
end
app/views/wait_lists/new.html.erb
<%= form_for(:wait_list, url: wait_lists_path) do |f| %>
<%= f.text_field :email, placeholder: "Email" %>
<%= f.submit "Join" %>
<% end %>
If you want to do validation on the email, I'd recommend keeping your WaitList model and including ActiveModel::Model — not all models have to inherit from ActiveRecord::Base, only when they need it.
app/models/wait_list.rb
class WaitList
include ActiveModel::Model
attr_reader :email
def initialize(email)
#email = email
post_initialize
end
validates(
:email,
presence: true,
format: { with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i }
)
private
def post_initialize
if email
email.downcase!
end
end
end
app/controllers/wait_lists_controller.rb
class WaitListsController < ApplicationController
def new
#wait_list = WaitList.new
end
def create
#wait_list = WaitList.new(wait_list_params)
if #wait_list.valid?
send_wait_list_email(#wait_list)
# redirect somewhere
else
render :new
end
end
private
def send_wait_list_email(wait_list)
WaitListMailer.wait_list_email(wait_list).deliver
end
def wait_list_params
params.require(:wait_list).permit(:email)
end
end
app/views/wait_lists/new.html.erb
<%= form_for(#wait_list) do |f| %>
<%= f.text_field :email, placeholder: "Email" %>
<%= f.submit "Join" %>
<% end %>
Hope that helps.
http://edgeguides.rubyonrails.org/action_mailer_basics.html#calling-the-mailer
http://api.rubyonrails.org/classes/ActiveModel/Model.html
If I'm entirely honest, I don't understand action mailers in their entirety and I'm finding it hard to discover a learning resource that isn't using an app which is of a completely different context (e.g teamtreehouses todo app). I would really appreciate a little help.
I have a business directory, I want each listings show page to have a form which when filled in, sends the entered info to the listings attached email.
Here's my code:
Mailers/Enquiry.rb
class Enquiry < ActionMailer::Base
default from: "admin#uk-franchise.co.uk"
def lead(listing, info)
#listing = listing
mail(to: #enquiry.email, subject: 'Email Testing Rails App')
mail(to: #listing.leadrecepient, subject: "test")
end
end
listings controller method
def lead
info = params[:leadname]
notifier = Notifier.lead(#listing, info)
end
Routes I'm stuck on configuring as I don't fully understand them for mailers.
What I have in the show listing view so far
<%= form_for lead_path(#leadname, #listing), method: :put do |lead| %>
<% end %>
Again, if anyone could provide me with a learning resource that would accommodate this scenario or a little help I would really appreciate it!
Here's what you have to do:
Do not use mail method twice in one method
class Enquiry < ActionMailer::Base
default from: "admin#uk-franchise.co.uk"
def lead(listing)
#listing = listing
mail(to: #listing.leadrecepient, subject: "test")
end
end
Send your email from within controller action:
class ListingsController
def lead
##listing = Listing...
Enquiry.lead(#listing).deliver
end
end
routes.rb:
# ...
resources :listings do
member do
put :lead
end
end
# ...
view:
<%= form_for lead_listing_path(#listing), method: :put do |listing| %>
<% end %>
I am a newbie in Rails , trying to make a contact form for my app, but I can not catch the parameters that comes from contact form (like name and message) in Emailer class without asscociating a model. Any suggestion on that? Here are the list of classes and controllers.
My Emailer class is :
class Contact < ActionMailer::Base
default from: "from#example.com"
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
# en.contact.send_email.subject
def send_email(contact)
#greeting = "Hi"
mail to: "ostadfree#gmail.com"
end
end
Staticpages controller is :
def email_contact()
Contact.send_email().deliver
redirect_to contact_url
end
Contact.html.erb is include a form and two buttons at the end:
<%= submit_tag "Submit", class: "btn btn-large btn-primary" %>
<%= link_to 'Send Email', email_contact_path %>
and send_email.text.erb is :
Contact#send_email
<%= #greeting %>, find me in app/views/app/views/contact/send_email.text.erb
<%#= "Name :" + #name.to_s %>
Thanks.
Based on your code, you really don't have a grasp on how rails is designed to work. You're probably better off following a tutorial than getting a question like this answered here.
http://seanrucker.com/simple-ruby-on-rails-contact-form-using-activemodel-and-pony/
Try this:
in mailer:
def send_email(name,message)
#greeting = "Hi"
#name = name
#message = message
mail to: "ostadfree#gmail.com"
end
in controller:
def email_contact()
Contact.send_email(params[:name],params[:message]).deliver
redirect_to contact_url
end
where name and message - names of form's fields. If it sent a mails before, that code should work.
Anyway, check it, really: http://guides.rubyonrails.org/action_controller_overview.html#parameters