hello I' am new at ruby on rails and I am trying to implement an email sender. I would like the email sender to send an email every time somebody types their email. But is not working for some reason, please help me.
class ZipMailer < ActionMailer::Base
default from: "Example#gmail.com"
def zip_email_confirmation(zip_mailer)
recipents zip_mailer
from "Example#gmail.com"
subject "Thanks from Example"
body :zip_mailer => zip_mailer
end
end
ActionMailer::Base.smtp_settings = {
:address =>"smtp.gmail.com",
:port =>587,
:domain =>"gmail.com",
:user_name =>"gmail",
:password =>"12345",
:authentication =>"plain",
:enable_starttls_auto => true
}
def create
#box = Box.new(box_params)
#TO DO: validations. return errors or save
if #box.save
ZipMailer.zip_email_confirmation(#zip_mailer).deliver
ConfirmMailer.box_alert(#box).deliver
session[:box_id] = #box.id
render 'charges/new'
else
render action: 'new'
end
<%= form_tag do %>
<%= email_field(:zip_mailer, :address) %>
<%= submit_tag("sub") %>
<% end %>
Related
I am going through this tutorial (link:https://www.murdo.ch/blog/build-a-contact-form-with-ruby-on-rails-part-1) to create a simple contact us form on my existing rails application. After completing the tutorial and testing on my development environment I notice that my smtp settings are interferring with my contact us form. Basically I just want send a message to an email address so I dont need the sender mail address for this. I tried removing the SMTP settings in my development.rb file but then I get this error when clicking the submit button:
Errno::ECONNREFUSED in MessagesController#create
Connection refused - connect(2) for "localhost" port 1025
I tried solving in different ways but I come back to this same error. Here's my code:
model/message.rb:
class Message
include ActiveModel::Model
attr_accessor :name, :email, :body
validates :name, :email, :body, presence: true
end
Here's my message controller:
class MessagesController < ApplicationController
def new
#message = Message.new
end
def create
#message = Message.new message_params
if #message.valid?
MessageMailer.contact_me(#message).deliver_now
redirect_to new_message_url, notice: "Message received"
else
render :new
end
end
def message_params
params.require(:message).permit(:name, :email, :body)
end
end
My view:new.html.erb:
<%= form_for #message, url: create_message_url do |f| %>
<%= notice %>
<%= #message.errors.full_messages.join(', ') %>
<%= f.text_field :name, placeholder: 'name' %>
<%= f.email_field :email, placeholder: 'email' %>
<%= f.text_area :body, placeholder: 'body' %>
<%= f.submit 'Send' %>
<% end %>
My Mailer:
class MessageMailer < ApplicationMailer
def contact_me(message)
#greeting = 'Hi'
#body = message.body
mail to: "notifications#example.com", from: message.email
end
end
And my Development.rb/SMTP settings code:
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default :charset => "utf-8"
config.action_mailer.smtp_settings = {
:address => 'localhost',
:port => 587,
:domain => 'localhost:3000',
:user_name => 'example#gmail.com',
:password => '######',
:authentication => 'plain',
:enable_starttls_auto => true
}
I just want to get rid of the smtp settings but unfortunately I cannot, is there any way to override these settings or an alternate solution or am I missing something,
Any help will be appreciated,
Thanks in advance
Please forgive the newbie question. I'm building a form that has a contact us page, in which a user should be able to fill out a form (user_full_name, user_email, subject, message), which when submitted should be sent as an email to my gmail address. I'm currently getting the following error when I try to access the view with the form on it.
undefined method `feedbacks_path' for #<#:0x007f8fefecd020>
below is my code, does anyone know what I'm doing wrong here? If possible I'd rather change the routes than add a url to the form. Also, want to use a 'match' in the routes to have the url path be 'localhost/contact' instead of 'localhost/feedback'. Does anyone have any ideas?
routes.rb
Sample::Application.routes.draw do
resources :feedback, only: [:new, :create]
root to: "home#index"
match '/about', to: 'static_pages#about', via: 'get'
match '/help', to: 'static_pages#help', via: 'get'
match '/privacy_policy', to: 'static_pages#privacy_policy', via: 'get'
match '/terms_and_conditions', to: 'static_pages#terms_and_conditions', via: 'get'
end
Feedback_Controller.rb
class FeedbackController < ApplicationController
def new
#feedback = Feedback.new
end
def create
#feedback = Feedback.new(params[:feedback])
if #feedback.valid?
FeedbackMailer.new_feedback(#feedback).deliver
flash[:success] = "We have receieved your message!"
redirect_to users_path
else
flash.now.alert = "Please fill in all fields."
render :new
end
end
end
Feedback.rb
class Feedback < ActiveRecord::Base
def self.columns() #columns ||= []; end
def self.column(name, sql_type = nil, default = nil, null = true)
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
end
column :user_full_name, :string
column :user_email, :string
column :subject, :text
column :body, :text
belongs_to :user
end
view/feedback.new.html.erb
<div class="feedback">
<div class="container">
<%= form_for #feedback do |f| %>
<%= f.hidden_field :user_full_name %>
<%= f.hidden_field :user_email %>
<%= f.label :subject %>
<%= f.text_field :subject %>
<%= f.label :feedback %>
<%= f.text_area :body %>
<%= f.submit "Send", class: "btn btn-inverse" %>
<% end %>
</div>
</div>
feedback_mailer
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
Name: <%= #feedback.user_full_name %>
Email: <%= #feedback.user_email %>
Subject: <%= #feedback.subject %>
Comments/Question: <%= #feedback.body %>
</body>
</html>
feedback_mailer.rb
class FeedbackMailer < ActionMailer::Base
default to: "railstraining09#gmail.com"
def new_feedback(feedback)
#feedback = feedback
mail(from: #user.email, subject: 'feedback.subject')
end
end
If you are in developement you could add in app/config/environments/development.rb
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
# Gmail SMTP server setup
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:enable_starttls_auto => true,
:port => 587,
:authentication => :plain,
:user_name => ENV['GMAIL_USERNAME'],
:password => ENV['GMAIL_PASSWORD']
}
and give it a try.
You can create instead a file mail.rb in config/environments/ or if you want to use a specific email account for each environment than you will need to write in each 'environments' file (production.rb; test.rb, development.rb) your ActionMailer::Base.smtp_settings { options .... }
P.S. I would suggest you to use mandrill/sendgrid etc instead video
I am new to Rails and trying to get a example working to register with a confirmation email with Rails 4 and devise. I am using this example:
https://github.com/mwlang/lazy_registration_demos
I created the following files:
initialisers/setup_mail.rb
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:user_name => "account#gmail.com",
:password => "passwork",
:authentication => "plain",
:enable_starttls_auto => true
}
/app/mailers/welcome_email.rb
class WelcomeMailer < ActionMailer::Base
def registration_confirmation(user)
mail :to => user, :from => "email#domain.com", :subject => "Subject line"
end
end
/devise/mailer/confirmations_instructions.html.erb
<p>
Welcome #{#email}!
</p>
<p>You can confirm your account email through the link below:</p>
<p>
<%= link_to 'Confirm my account', confirmation_url(#resource, :confirmation_token => #resource.confirmation_token) %>
</p>
confirmations_controller.rb
class ConfirmationsController < Devise::ConfirmationsController
# Remove the first skip_before_filter (:require_no_authentication) if you
# don't want to enable logged users to access the confirmation page.
skip_before_filter :require_no_authentication
skip_before_filter :authenticate_user!, except: [:confirm_user]
def update
with_unconfirmed_confirmable do
if confirmable_user.blank_password?
confirmable_user.update_password(params[:user])
if confirmable_user.valid?
do_confirm
else
do_show
confirmable_user.errors.clear # prevent rendering :new
end
else
self.class.add_error_on(self, :email, :password_allready_set)
end
end
render 'devise/confirmations/new' unless confirmable_user.errors.empty?
end
def confirm_user
if confirmation_token && (#confirmable_user = User.find_by(:confirmation_token => confirmation_token))
do_show
else
flash[:error] = "Invalid confirmation token"
redirect_to :unconfirmed
end
end
def show
with_unconfirmed_confirmable do
confirmable_user.blank_password? ? do_show : do_confirm
end
unless confirmable_user.errors.empty?
self.resource = confirmable_user
render 'devise/confirmations/new'
end
end
protected
def confirmation_token
#confirmation_token ||= params["user"] && params["user"]["confirmation_token"] || params["confirmation_token"]
end
def confirmable_user
#confirmable_user ||= User.find_or_initialize_with_error_by(:confirmation_token, confirmation_token)
end
def with_unconfirmed_confirmable
unless confirmable_user.new_record?
confirmable_user.only_if_unconfirmed {yield}
end
end
def do_show
self.resource = confirmable_user
render 'devise/confirmations/show'
end
def do_confirm
confirmable_user.confirm!
set_flash_message :notice, :confirmed
sign_in_and_redirect(resource_name, confirmable_user)
end
end
/devise/registrations/new.html.haml
%h2 Sign up
= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
= devise_error_messages!
%div
= f.label :email
= f.email_field :email, :autofocus => true
%div{style: "margin-top: 25px"}= f.submit "Sign up", class: "btn btn-primary btn-large"
%hr
= render "devise/shared/links"
To trigger the email to be send I need to add
WelcomeMailer.registration_confirmation(#user).deliver
But I have no clue where I need to add this trigger. Do I need to do this in the controller? Or in the view?
Thanks a lot
Managed to fix this issue myself using mailcatcher
Steps to fix:
clone github project lazy_registrations
gem install mailcatcher
add lines to /environments/development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 }
run mailcatcher
check email using 127.0.0.1:1080
ignore all other code above, just needed a night of sleep :)
First off, i know attr_accessible is deprecated in Rails 4, but what about attr_accessor?
When you hit submit it's returning a "Template is Missing" error, but that's because its hitting an error somewhere in the send proccess then just trying to return "connect#create" which doesn't exist as a physical page.
When i check the log files, I am getting a 500 internal server error when trying to send a contact form, and I'm not sure if using attr_accessor in Rails 4 is the culprit. Is there a newer way to write this?
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :phone, :subject, :company, :title, :market, :body
validates :name, :email, :subject, :company, :body, :presence => true
validates :email, :format => { :with => %r{.+#.+\..+} }, :allow_blank => true
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
The above is the message model for the contact form:
Is it something within the process of sending the data?
The rest of the code for the contact mail functionality is:
Contact Mailer
class ContactMailer< ActionMailer::Base
default :from => "noreply#test.com"
default :to => "{{MY EMAIL}}"
def new_message(message)
#message = message
mail(:subject => "Test Message")
end
end
In /views/contact_mailer/ there is a new_message.text.erb file:
Name: <%= #message.name %>
Email: <%= #message.email %>
Phone: <%= #message.phone %>
Subject: <%= #message.subject %>
Company: <%= #message.company %>
Title: <%= #message.title %>
Market: <%= #message.market %>
Body: <%= #message.body %>
My Routes are:
match 'connect' => 'connect#index', :as => 'connect', :via => :get
match 'connect' => 'connect#create', :as => 'connectpost', :via => :post
The connect page controller:
class ConnectController < ApplicationController
def index
#message = Message.new
end
def create
#message = Message.new(params[:message])
if #message.valid?
NotificationsMailer.new_message(#message).deliver
redirect_to(connect_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
render :new
end
end
end
And finally....the SMTP settings in /config/initializers/smtp_settings.rb
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "{{SITE DOMAIN}}",
:user_name => "{{GMAIL EMAIL}}",
:password => "{{GMAIL EMAIL PASSWORD}}",
:authentication => "plain",
:enable_starttls_auto => true
}
My ConnectController#Create was trying to initialize
NotificationMailers.new_message()
But it needed to be:
ContactMailer.new_message()
I have no idea why the tutorial I followed would have the wrong class name there...but that was the issue.
Thanks all.
attr_accessor, attr_writer and attr_reader are all part of vanilla core Ruby and are helper methods for Modules and Classes.
They work fine in Ruby 2.0, so you'll have to mark them off your suspect list.
I had a question earlier on this, I am trying to make a ldap search form.
So far I did rails generate for users/find. In the model I have a function to search a user in ldap, which works fine independently outside of rails.
but the request through this view is actually getting treated as a request to create a new user, instead to just search the user in ldap.
I am new to rails, dont what the missing link is. Need some help here understanding this, in future there will be a lot of functions/features like this I have to add in this test app. Which I think will probably lead to the same issue.
# rails generate controller users find
error -
undefined method `gsub' for nil:NilClass
Started GET "/users/find" for 10.85.41.23 at 2012-04-05 19:56:27 -0400
Processing by UsersController#find as HTML
Completed 500 Internal Server Error in 15ms
NoMethodError (undefined method `gsub' for nil:NilClass):
app/models/user.rb:54:in `FindActiveDirectory'
app/controllers/users_controller.rb:10:in `find'
Model -
class User < ActiveRecord::Base
attr_accessible :user_id, :firstname, :lastname, :email, :role, :misc, :password
validates_presence_of :user_id, :firstname, :lastname, :email, :role, :on => :create
validates_uniqueness_of :user_id, :email
ROLES = ['Admin','User']
####################
SERVER = '10.10.10.1'
PORT = 389
BASE = 'DC=User,DC=mysite,DC=com'
DOMAIN = 'ldap.mysite.com'
####################
def self.ActiveDirectoryAuthenticate(login, pass)
user = find_by_user_id(login)
if user
nil
else
return false
end
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => { :username => "#{login}##{DOMAIN}",
:password => pass,
:method => :simple }
if conn.bind
return user
else
return false
end
rescue Net::LDAP::LdapError => e
return false
end
def self.FindActiveDirectory(login)
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => { :username => 'admin',
:password => 'adminpass',
:method => :simple }
if conn.bind
conn.search(:base => BASE, :filter => Net::LDAP::Filter.eq( "sAMAccountName", login ),
:attributes => ['givenName','SN','mail'], :return_result => true) do |entry|
entry.each do |attributes, values|
if "#{attributes}" == "sn"
values.each do |value|
puts "Lastname: "+"#{value}"
$lastname = "#{value}"
end
end
if "#{attributes}" == "givenname"
values.each do |value|
puts "Firstname: "+"#{value}"
$firstname = "#{value}"
end
end
if "#{attributes}" == "mail"
values.each do |value|
puts "Email: "+"#{value}"
$email = "#{value}"
end
end
end
end
return true
else
return false
end
rescue Net::LDAP::LdapError => e
return false
end
end
controller -
class UsersController < ApplicationController
def new
#user = User.new
end
def find
#user = User.FindActiveDirectory(params[:user_id])
end
def create
#user = User.new(params[:user_id])
if #user.save
redirect_to users_added_url, :notice => "Signed up!"
else
render "new"
end
end
end
View -
<h1>Users#find</h1>
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :Username %><br />
<%= f.text_field :user_id %>
</p>
<p class="button"><%= f.submit %></p>
<% end %>
routes -
rubyapp::Application.routes.draw do
get "users/find"
get "myapp/new"
root :to => "sessions#new"
#root :to => "home#index"
get "sessions/new"
get "users/new"
get "users/added" => "users#added"
get "myapp" => "myapp#new"
get "log_out" => "sessions#destroy", :as => "log_out"
get "log_in" => "sessions#new", :as => "log_in"
get "sign_up" => "users#new", :as => "sign_up"
resources :users
resources :sessions
end
You need another method to handle the data you returned:
the controller:
def find
end
def display_result
#result = User.findActiveDirectory( params[:user_id] )
if #result.empty?
render action: "find", notice: "Could not find a user with id #{params[:user_id]}"
end
end
next step is to add a route to the routes.rb:
get 'users/find'
post 'users/display_result'
now we have to update the view for find:
<h1>Users#find</h1>
<p><%= notice %></p>
<%= form_tag users_display_result_path do %>
<p>
<%= label_tag :Username %><br />
<%= text_field_tag :user_id %>
</p>
<p class="button"><%= submit_tag %></p>
<% end %>
and create the new view for displaying the result (this one is very basic, i guess you need to improve this a lot, but this should give you an idea):
<h1>Users#display_result</h1>
<%= debug #result %>
and last but not least change some stuff in the model:
def self.FindActiveDirectory(login)
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => { :username => 'admin',
:password => 'adminpass',
:method => :simple }
if conn.bind
result = HashWithIndifferentAccess.new
conn.search( :base => BASE,
:filter => Net::LDAP::Filter.eq( "sAMAccountName", login ),
:attributes => ['givenName','SN','mail'],
:return_result => true
) do |entries|
entries.each do |attribute, value|
result[attribute] = value
end
end
return result
rescue Net::LDAP::LdapError => e
return false
end
You will end up in the controller/ view with a variable called #result. This variable is a hash with the attributes as key. So you could do something like this in the view:
<% #result.each do |key,value| %>
<%= key.to_s.normalize + ": " + value.to_s %>
<% end >