I'm using careerfoundry's tutorial on using Sendgrid to send emails with Heroku. I'm using their exact code for the user mailer and thank_you action in the pages controller. This code is working for the most part. The issue is that the subject line I receive in my inbox is this:
A new contact form message from #{name}
User_Mailer.rb
class UserMailer < ActionMailer::Base
default from: "from#example.com"
def contact_form(email, name, message)
#message = message
mail(:from => email,
:to => 'your-email#example.com',
:subject => "A new contact form message from #{name}")
end
end
Contact Form
<%= form_tag("/thank_you") do %>
<div class="row">
<div class="col-md-4">
<div class="input-group">
<%= text_field_tag :name, nil, class: 'form-control', placeholder: 'Name' %>
</div>
</div>
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">#</span>
<%= text_field_tag :email, nil, class: 'form-control', placeholder: 'Email' %>
</div>
</div>
</div>
<br>
<div class="row">
<div class="col-md-12">
<div class="input-group text-area-wide">
<%= text_area_tag :message, nil, class: 'form-control text-area-wide', placeholder: 'Message' %>
</div>
</div>
</div>
<br>
<%= submit_tag 'Send Message', class: 'btn btn-success' %>
<% end %>
Pages Controller
def thank_you
#name = params[:name]
#email = params[:email]
#message = params[:message] || "Hello!"
# Only try to send this email on a POST
# if request.post?
# or make a feedback form controller and send in the create action
# ActionMailer::Base.mail( FOR TEST PURPOSES
# :from => #email,
# :to => 'erikvdw#comcast.net',
# :subject => "A new contact form message from #{#name}",
# :body => #message).deliver
UserMailer.contact_form(#email, #name, #message).deliver
end
A quick fix would be to just split the string into two parts as such
class UserMailer < ActionMailer::Base
default from: "from#example.com"
def contact_form(email, name, message)
#message = message
mail(:from => email,
:to => 'your-email#example.com',
:subject => "A new contact form message from " + name) <----
end
end
This way the notation is clearer and it will avoid the manual concatenation problem.
After looking up a quick thing, it seems like this might also work. The single quotes are needed internally apparently according to a couple sources I found. I don't use that notation so let me know if it helped!
:subject => "A new contact form message from '#{name}'")
Related
What I wanted to do is get the
last_insert_id
of a table and insert it into another table but I get this error while doing it this way(I don't know if this is the right way to do such things)
ActiveModel::UnknownAttributeError (unknown attribute 'content' for MessagePicture.): # This is copied from the console
unknown attribute 'content' for MessagePicture. # Copied from the Browser and it had this number highlighted
#message = current_user.messages.build.message_pictures.build(message_params)
This is the
new and create methods of the Message_controller class
def new
#message = current_user.messages.build if logged_in?
#reciever = User.find_by(params[:id])
end
def create
##msg = Message.new(user_params)
#message = current_user.messages.build.message_pictures.build(message_params)
if #message.save
if #message[:picture].present?
# Send this to the message model for insertion with the #message_id and from the picture model, insert it to the
add_msg_pic(msg = [#message.id,#message[:msg_img_url]])
end
flash[:success] = "Message sent"
redirect_to messages_path
else
flash.now[:danger] = "Message not sent"
render 'new'
end
end
This is the
message_params method
def message_params
params.require(:message).permit(:content, :receiver, :sender, :archive, message_pictures_attributes:[:msg_img_url, :message_id])
end
This is the
Message class(model) add_msg_pic method
def add_msg_pic(msg)
msg.message_pictures.each.do |m|
m.message.id = nil
message_pictures << m
end
This is the view page
<h1>Compose a new message</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#message, html: { multipart: true }) do |f| %>
<%= render 'shared/error_messages', object: #message %>
<%= f.label :content %>
<%= f.hidden_field :receiver, value: #reciever %>
<%= f.hidden_field :sender, value: current_user.id %>
<%= f.text_area :content, size:"20x15" %>
<%= f.submit "Send message", class: "btn btn-primary" %>
<span class="picture">
<%= f.fields_for :message_pictures do |mp| %>
<%= mp.file_field :msg_img_url, accept: 'image/jpeg,image/gif,image/png' %>
<% end %>
</span>
<% end %>
<%= button_to "Save message", archive_messages_path %>
</div>
</div>
Assuming Message looks like this
class Message < ApplicationRecord
has_many :message_pictures
accepts_nested_attributes_for :message_pictures
end
Then this:
#message = current_user.messages.build.message_pictures.build(message_params)
should actually be
#message = current_user.messages.build(message_params)
Right now you are passing all of those attributes to a new MessagePicture but really you should be passing some to the Message and some to the MessagePicture.
The accepts_nested_attributes_for will slice off the ones for message_pictures via message_pictures_attributes and build both items for you.
I'm using contact_us gem and it was working well until I added another mailer. The second mailer is working well but the contact_us form works just when the email field is my default from email in another mailer! Here are the files and settings:
contact_us.rb
# Use this hook to configure contact mailer.
ContactUs.setup do |config|
# ==> Mailer Configuration
# Configure the e-mail address which email notifications should be sent from. If emails must be sent from a verified email address you may set it here.
# Example:
# config.mailer_from = "contact#please-change-me.com"
config.mailer_from = nil
# Configure the e-mail address which should receive the contact form email notifications.
config.mailer_to = "hi#mysite.com"
# ==> Form Configuration
# Configure the form to ask for the users name.
config.require_name = false
# Configure the form to ask for a subject.
config.require_subject = false
# Configure the form gem to use.
# Example:
# config.form_gem = 'formtastic'
config.form_gem = nil
# Configure the redirect URL after a successful submission
config.success_redirect = '/'
end
application_mailer.rb
class ApplicationMailer < ActionMailer::Base
end
my_mailer.rb
class MyMailer < ApplicationMailer
default from: "\"mysite\" <hi#mysite.com>"
layout 'mailer'
#The email that should be sent to the Passenger after his successful payment
def payment_confirmation(user, trip, seats, code)
...
mail(to: #user.email, subject: "...")
end
end
and my contact_us form is like this:
<% #contact = ContactUs::Contact.new %>
<%= form_for #contact, :url => contacts_path, :id => "contact-form", :html => {:class => 'formtastic'} do |f| %>
<div class="input-group name-email">
<div class="input-field">
<%= f.text_field :name, :id => "name", :placeholder => "نام", :class => "form-control" %>
</div>
<div class="input-field">
<%= f.text_field :email, :id => "email", :placeholder => "ایمیل*", :class => "form-control" %>
<% if f.object.errors[:email].present? %>
<p class='inline-error'><%= f.object.errors[:email].join(' and ') %></p>
<% end %>
</div>
</div>
<div class="input-group">
<%= f.text_area :message, :id => "message", :placeholder => "پیغام*", :class => "form-control" %>
</div>
<div class="input-group">
<%= f.submit "ارسال پیغام", :id => "form-submit", :class => "pull-left" %>
</div>
<% end %>
So, the problem is that it works only when the user submits hi#mysite.com as his mail address in the contact_us form!!
Any idea and help would be appreciated ...
I'm trying to build my first contact form, that would send someone's name, email and message to my email address to me. I've seen quite a lot of tutorials and answered questions on stackoverflow, but it didn't help me to fix the problem I'm having. I know it has something to do with the routing but I can't figure what and why.
I'm getting the following error:
Routing Error
uninitialized constant ContactController
Here are my files :
routes.rb
match '/send_mail', to: 'contact#send_mail', via: 'post'
match '/mail', to: 'contact#contact', via: 'get'
controllers/contacts_controller.rb
def send_mail
name = params[:name]
email = params[:email]
body = params[:comments]
ContactMailer.contact_email(name, email, body).deliver
redirect_to contact_path, notice: 'Message sent'
end
mailers/contact_mailer.rb
class ContactMailer < ActionMailer::Base
default to: 'mymail#gmail.com'
def contact_email(name, email, body)
#name = name
#email = email
#body = body`enter code here`
mail(from: email, subject: 'Contact Request')
end
end
views/contact.html.twig
<div class="container-content">
<div class="container">
<%= form_tag(send_mail_path) do %>
<div class="form-group">
<%= label_tag 'name', 'Name' %>
<%= text_field_tag 'name', nil, class: 'form-control', placeholder: 'John Doe' %>
</div>
<div class="form-group">
<%= label_tag 'email', 'Email' %>
<%= email_field_tag 'email', nil, class: 'form-control', placeholder: 'johndoe#domain.com' %>
</div>
<div class="form-group">
<%= label_tag 'comments', 'Comments' %>
<%= text_area_tag 'comments', nil, class: 'form-control', rows: 4, placeholder: 'How can I help you?' %>
</div>
<%= submit_tag nil, class: 'btn btn-default btn-about' %>
<% end %>
</div>
</div>
views/contact_email.html.erb
<!DOCTYPE html>
<html>
<head>
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<p>Mail received from <%= "#{ #name } (#{ #email }):" %></p>
<p><%= #body %></p>
</body>
</html>
config/initializers.rb
module Contact
class Application < Rails::Application
config.action_mailer.delivery_method = :sendmail
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.active_record.raise_in_transactional_callbacks = true
end
end
initializers/stmp_config.rb
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:user_name => "mymail#gmail.com",
:password => "password",
:authentication => :login,
:enable_starttls_auto => true
}
As I'm newbie in the rails world, I'm not sure at all of what I'm doing, but I've seen a lot of tutorials where people had a code similar to mine, but no one seems to have this problem
Where did i go wrong ?
Thank you in advance
You may want to change your routes.rb as follows (contacts instead of contact):
match '/send_mail', to: 'contacts#send_mail', via: 'post'
match '/mail', to: 'contacts#contact', via: 'get'
Thats one way to create a contact form - however its not really a Rails app. Its just an app that happens to be using Rails.
This is how you can use the Rails conventions to make this more robust and less messy.
Model
Lets generate a model and migration:
$ rails g model enquiry name:string email:string body:text
Then we run the migration:
$ rake db:migrate
So why create a model if we are just sending an email? Because email fails. And you don't want to lose important enquiries from potential customers.
We also want our model to validate that the user provides the required fields:
# app/models/enquiry.rb
model Enquiry < ActiveRecord::Base
validates_presence_of :name, :email, :body
validates_format_of :email, with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
end
Controller
Lets create a RESTful route:
# config/routes.rb
# ...
resources :enquiries, only: [:new, :create]
Note that we are calling it enquiries. Instead of using an procedure oriented send_contact route we have the resource enquiries which gives us conventions for how to show, create and update it.
You can see what routes are generated with $ rake routes.
See Resource Routing: the Rails Default.
Lets create a controller for our new route:
# app/controllers/enquiries_controller.rb
# note controllers use the plural form
class EnquiriesController < ApplicationController
# GET '/enquiries/new'
def new
#enquiry = Enquiry.new
end
# POST '/enquiries'
def create
#enquiry = Enquiry.new(enquiry_params)
if #enquiry.save
ContactMailer.contact_email(name, email, body).deliver
redirect_to root_path, success: 'Thanks for getting in touch, we will look into it ASAP.'
else
render :new
end
end
private
def enquiry_params
params.require(:enquiry).permit(:name, :email, :body)
end
end
View
We also need a form:
# app/views/enquiries/new.html.erb
<%= form_for(#enquiry) do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :name %>
</div>
<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body %>
</div>
<%= f.submit %>
<% end %>
By using a form builder and a model our form will automatically "play back" the values if the user submits an invalid form.
Your problem in 'ContactController' - it's must be in plural: 'ContactsController'!
I have three mailers, all of which work. But for one (the contact form) the mailer preview doesn't work and I don't understand why.
The error message:
undefined method 'email'
def new_message(message)
#message = message
mail from: message.email, subject: "Message from #{message.name}"
end
In app/mailers/message_mailer.rb I have:
class MessageMailer < ApplicationMailer
default to: "<info#myemail.com>",
return_path: "<info#myemail.com>"
def new_message(message)
#message = message
mail from: message.email, subject: "Message from #{message.name}"
end
end
Part of app/views/messages/new.html.erb:
<%= form_for :message, url: contact_path do |f| %>
<%= f.label :name %>
<%= f.text_field :name, placeholder: 'Name', class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, placeholder: 'Email', class: 'form-control' %>
<%= f.label :content %>
<%= f.text_area :content, placeholder: 'Your message…', class: 'form-control' %>
<%= f.submit "Send", class: "btn btn-primary" %>
<% end %>
test/mailers/previews/test_mailer_preview.rb:
class MessageMailerPreview < ActionMailer::Preview
message = [name: "My Name", email: "noreply#example.com", content: "This is my message"]
MessageMailer.new_message(message)
end
end
The contact form is properly working on the development server, and the other two mailers (password reset and authentication) also work and for these last two mailers the previews also work properly. These two mailers also have model.email in the mailer, and there it does work. I don't understand why the preview for the contact form mailer produces the error message.
I turns out that if I replaced
message = [name: 'My Name', email: 'noreply#example.com', content: 'This is my message']
with
message = Message.first
message.email = "example#example.com"
or even just
message = Message.first
the preview does work. Don't understand why since I would expect the original formulation also to work.
Your mailer class isn't inherited from ActionMailer, which is fine if you have an ApplicationMailer class doing that already, can you post the code for it please? Otherwise try this.
class MessageMailer < ActionMailer::Base
I would like user to input regex using form and text_field tag. But as I understand it is being sanitized by default. If I store regexs directly in DB via seed.rb or console, it works. But I cannot do it using UI:
<div class="control-group">
<%= f.label :regexp, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :regexp, :class => 'text_field' %>
</div>
</div>
How to fix it?
Here is a solution:
Overriding the getter method with a regex parsing method that you define on the model will work. So now if you enter in a regex through the UI like /\d+/ it will serialize to "/\\d+/" to store in the database. But when you call the instance of user.regex it will be parsed into a Regexp object which you can call match on.
Example:
u = User.create(regex: "/\\d+/")
u.regex => /\d+/
u.regex.class => Regexp
u.regex.match("12345") => #<MatchData "12345">
u.regex.match("12345abc") => #<MatchData "12345">
Model:
class User < ActiveRecord::Base
def regex
parse_regex(self[:regex])
end
def parse_regex(string)
pieces = string.split("/")
pattern = pieces[1]
flags = pieces[2]
arg_two = 0
if flags.present?
flags.length.times do |i|
case flags[i, 1]
when "i"
arg_two |= Regexp::IGNORECASE
when "m"
arg_two |= Regexp::MULTILINE
when "x"
arg_two |= Regexp::EXTENDED
end
end
end
Regexp.new(pattern, arg_two)
end
end
Controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params).save
end
private
def user_params
params.require(:user).permit(:regex)
end
end
View:
<%= form_for #user do |f| %>
<%= f.label :regex %>
<%= f.text_field :regex %>
<%= f.submit %>
<% end %>