I want to be able to send a new user's ip address to my admin account when a new user signs up. I have:
class UserMailer < ActionMailer::Base
default :from => '"Admin" <support#mysite.com>'
def registration_confirmation(user)
#user = user #needed in order to have access to user variables
def client_ip
#client_ip = request.remote_ip
end
mail(:to => "#{user.name} <#{user.email}>", :subject => "Welcome to MySite").deliver!
mail(:to => '"Admin" <support#mysite.com>',
:subject => "New Member",
:body => "New member #{user.name} with email #{user.email} and ip: #{#client_ip} has just signed up!",
:content_type => "text/html")
end
end
I'm getting the error:
NameError in UsersController#create
undefined local variable or method `request' for #
users_controller.rb
def create
#user = User.new(params[:user])
if #user.save
UserMailer.registration_confirmation(#user).deliver
sign_in #user
redirect_to #user
else
render 'new'
end
end
Something like:
def create
#user = User.new(params[:user])
if #user.save
UserMailer.registration_confirmation(#user, request.remote_ip).deliver
sign_in #user
redirect_to #user
else
render 'new'
end
end
def registration_confirmation(user, client_ip = '0.0.0.0')
#user = user #needed in order to have access to user variables
mail(:to => "#{user.name} <#{user.email}>", :subject => "Welcome to MySite").deliver!
mail(:to => '"Admin" <support#mysite.com>',
:subject => "New Member",
:body => "New member #{user.name} with email #{user.email} and ip: #{client_ip} has just signed up!",
:content_type => "text/html")
end
You only have access to the request object in the controller/view. So you need to pass the value along to the mailer if that is where you want to have access to it.
Related
I'm working on a application which contains the soundcloud api.
i have the user login and model and i would like to append the soundcloud_id and token to the existing user but i cannot somehow update the users record.
what do i do wrong?
soundcloud controller
class SoundcloudController < ApplicationController
def connect
# create client object with app credentials
client = Soundcloud.new(:client_id => ENV["SOUNDCLOUD_CLIENT_ID"],
:client_secret => ENV["SOUNDCLOUD_CLIENT_SECRET"],
:redirect_uri => "http://localhost:3000/soundcloud/oauth-callback",
:response_type => 'code')
# redirect user to authorize URL
redirect_to client.authorize_url(:grant_type => 'authorization_code', :scope => 'non-expiring', :display => 'popup')
end
def connected
# create client object with app credentials
client = Soundcloud.new(:client_id => ENV["SOUNDCLOUD_CLIENT_ID"],
:client_secret => ENV["SOUNDCLOUD_CLIENT_SECRET"],
:redirect_uri => "http://localhost:3000/soundcloud/oauth-callback")
# exchange authorization code for access token
access_token = client.exchange_token(:code => params[:code])
client = Soundcloud.new(:access_token => access_token["access_token"])
# make an authenticated call
soundcloud_user = client.get('/me')
unless User.where(:soundcloud_user_id => soundcloud_user["id"]).present?
#User.create_from_soundcloud(soundcloud_user, access_token)
UsersController.add_soundcloud_account(soundcloud_user, access_token)
end
sign_in_user = User.where(:soundcloud_user_id => soundcloud_user["id"])
#create user sessions
#session[:user_id] = sign_in_user.first.id
redirect_to root_url, notice: "Signed in!"
end
def destroy
end
end
user controller
class UsersController < ApplicationController
def new
#user = User.new
end
#create a user and redirect to home
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to '/'
else
redirect_to '/signup'
end
end
def self.add_soundcloud_account(soundcloud_user, access_token)
#current_user ||= User.find(session[:user_id])
#current_user.soundcloud_user_id = soundcloud_user["id"]
#current_user.soundcloud_access_token = access_token["access_token"]
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password)
end
end
You need to call save on the #current_user and pass in the session information to the method:
def self.add_soundcloud_account(user_id, soundcloud_user, access_token)
#current_user ||= User.find(user_id)
#current_user.soundcloud_user_id = soundcloud_user["id"]
#current_user.soundcloud_access_token = access_token["access_token"]
#current_user.save
end
It is called like this:
UsersController.add_soundcloud_account(session[:user_id], soundcloud_user, access_token)
However I am not sure the add_soundcloud_account method belongs in a controller. I would prefer to see it in a Service or maybe just in the User model.
I'm using devise with my Rails 4 app.
I have the following in my user.rb model:
def send_admin_mail
AdminMailer.new_user_waiting_for_approval(self).deliver
end
def send_user_welcome_mail
AdminMailer.new_user_waiting_for_access(user).deliver
end
The first method sends me an email when a new user registers. The aim is for the second method to send a welcome email to the new user. The first method works. The second raises an issue with 'no_method_error' (undefined method email in my callbacks controller).
My callback controller has the following:
def linkedin
#user = User.find_for_linkedin_oauth(request.env["omniauth.auth"])
if #user.persisted?
#user.send_admin_mail
#user.send_user_welcome_mail
redirect_to root_path, :event => :authentication
# sign_in_and_redirect #user, :event => :authentication #this will throw if #user is not activated
# set_flash_message(:notice, :success, :kind => "LinkedIn") if is_navigational_format?
else
session["devise.linkedin_data"] = request.env["omniauth.auth"]
redirect_to root_path
end
end
My admin_mailer has:
def new_user_waiting_for_approval(user)
#user = user
mail(to: "myemailaddress#gmail.com", from: "myemailaddress#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: "myemailaddress#gmail.com", subject: "Welcome to Co #{user.first_name}")
end
I'm wondering whether I need to replace user with current_user to make use of the devise method or maybe whether some variation on {} and/or "" is required around the user.email in the second method?? I've tried a few different variations and combinations but haven't had any success.
Thank you for your help.
def send_user_welcome_mail
AdminMailer.new_user_waiting_for_access(user).deliver
end
should be replaced with
def send_user_welcome_mail
AdminMailer.new_user_waiting_for_access(self).deliver
end
user -> self
I am trying to generate mails with rails action mailer, but it seems like it is not doing everything completely right:
Here's where I create my mail:
class UserNotifier < ActionMailer::Base
default from: 'mail#mail.com'
def forgot_password(user)
setup_email(user)
#subject += "Password restoration"
#url = url_for :controller => 'user_session', :action => 'reset_password',
:id => user.pw_reset_code, :only_path => true
end
protected
def setup_email(user)
#subject = "[MY APP] "
#sent_on = Time.now
#user = user
#content_type = "text/html"
mail to: user.email
end
end
And here's the html.erb that contains the mail.
<%= #user.name %>,
<br/><br/>
Restore password:
<%= #url %>
However, the subject of the mail is not what I said it should be.
But most importantly, #url is nil in the html.erb, however it is generated correctly in forgot_password, I tested it.
Why is it nil? And what can I do to render the URL?
Mails are sent when you call method deliver on ActionMailer::Base object.
Your method forgot_password does not return this object.
the line mail(to: .....) should be the last one in the forgot_password routine
Run rails console and type this to see what returns
ActionMailer::Base::mail(to: 'example.com', subject: 'hello')
then call #deliver on it.
The line
mail to: user.email
Is actually causing your email to send.
Because you are calling this in setup_email, you are actually sending the email AND THEN trying to change the subject and URL after it is sent.
If you ignore the setup method that you have for a second, this is what your code would look like in the order you currently have it:
#subject = "[MY APP] "
#sent_on = Time.now
#user = user
#content_type = "text/html"
mail to: user.email << MAIL IS SENT HERE
#subject += "Password restoration"
#url = url_for :controller => 'user_session', :action => 'reset_password',
:id => user.pw_reset_code, :only_path => true
Update your code to call the mail command last, for example:
def forgot_password(user)
setup_email(user)
#subject += "Password restoration"
#url = url_for :controller => 'user_session', :action => 'reset_password',
:id => user.pw_reset_code, :only_path => true
mail to: user.email
end
protected
def setup_email(user)
#subject = "[MY APP] "
#sent_on = Time.now
#user = user
#content_type = "text/html"
end
I set up a basic sign in, login, sign out format for a rails app and I was going to give it a function so that if a person forgot their password they could get a email back. when I went click on submit password reset I got
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
Extracted source (around line #3):
1: To reset your password click the URL below.
2:
3: <%= edit_password_reset_url(#user.password_reset_token) %>
4:
5: If you did not request your password to be reset please ignore this email and your password will stay as it is.
Rails.root: /Users/cheatermoves/nightclass/mainproject/project
Application Trace | Framework Trace | Full Trace
app/views/user_mailer/password_reset.text.erb:3:in `_app_views_user_mailer_password_reset_text_erb__3613112772785486465_70118994937040'
app/mailers/user_mailer.rb:6:in `password_reset'
app/models/user.rb:17:in `send_password_reset'
app/controllers/password_resets_controller.rb:7:in `create'
just completed rails cast 250 and was doing 274. Everything was fine until I got this problem.
here is my controllers. Password resets:
class PasswordResetsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
user.send_password_reset if user
redirect_to root_url, :notice => "Email sent with password reset instructions."
end
end
sessions:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
if params[:remember_me]
cookies.permanent[:auth_token] = user.auth_token
else
cookies[:auth_token] = user.auth_token
end
redirect_to root_url, :notice => "Logged in!"
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
def destroy
cookies.delete(:auth_token)
redirect_to root_url, :notice => "Logged out!"
end
end
users:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
session[:user_id] = #user.id
redirect_to root_url, notice: "Thank you for signing up!"
else
render "new"
end
end
end
and application:
class ApplicationController < ActionController::Base
protect_from_forgery
private
def current_user
#current_user ||= User.find_by_auth_token( cookies[:auth_token]) if cookies[:auth_token]
end
helper_method :current_user
end
in environments/development.rb I have
config.action_mailer.default_url_options = { :host => "localhost:3000" }
here is my user model
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
validates_presence_of :password, :on => :create
before_create { generate_token(:auth_token) }
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
end
user_mailer.rb file
class UserMailer < ActionMailer::Base
default from: "from#example.com"
def password_reset(user)
#user = user
mail :to => user.email, :subject => "Password Reset"
end
end
anyone know what the problem is and how to fix it? I'm using rails 3.2.14 if anyone is wondering. Thanks!
Didn't read the part where you said that you already set your
config.default_url_options[:host] = "localhost:3000"
my bad, sorry
In my ROR app, I am trying to send confirmation emails to my registered users when they signup, my website is on localhost currently. I am getting this error:
"undefined method `recipients' for #<UserMailer:0x3d841a0>"
Here is my code;
development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { :host => "localhost:3000"}
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => "587",
:authentication => :login,
:user_name => "myemailid#gmail.com",
:password => "myrealpassword"
}
Users_controller.rb
def new
UserMailer.registration_confirmation(#user).deliver
end
def create
#user = User.new(params[:user])
if #user.save
UserMailer.registration_confirmation(#user).deliver
sign_in #user
flash[:success] = "Welcome!"
redirect_to #user
else
render 'new'
end
end
user_mailer.rb
class UserMailer < ActionMailer::Base
def registration_confirmation(user)
recipients user.email
from "myemailid#gmail.com"
subject "Thank you for registration"
body :user => user
end
end
** development.rb**
config.action_mailer.delivery_method = :sendmail
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
** Users_controller.rb **
def new
UserMailer.registration_confirmation(#user).deliver
end
def create
#user = User.new(params[:user])
if #user.save
UserMailer.registration_confirmation(#user).deliver
sign_in #user
flash[:success] = "Welcome!"
redirect_to #user
else
render 'new'
end
end
** User_mailer.rb **
def registration_confirmation(user)
#message = 'whatever you want to say here!'
mail(:from => "myemailid#gmail.com", :to => user.email, :subject => "Thank you for registration")
end
**/app/views/user_mailer/registration_confirmation.text.erb *
<%= #message %>
That's what I've done in my development mode, and it works
What version of Rails are you using?
Sending of email changed in version 3.2 (I believe)
http://api.rubyonrails.org/classes/ActionMailer/Base.html
Try:
UserMailer.registration_confirmation(#user).deliver
This is your user_mailer.rb
user_mailer.rb
class UserMailer < ActionMailer::Base
def registration_confirmation(user)
recipients user.email
from "myemailid#gmail.com"
subject "Thank you for registration"
body :user => user
end
Try instead:
class UserMailer < ActionMailer::Base
default from: "myemailid#gmail.com"
def registration_confirmation(user)
mail(to: user.email, subject: "Thank you for registration")
end
end
And set up the appropriate view in views/user_mailer e.g. registration_confirmation.html.erb