how to identify the method name that calling the particular function? - ruby-on-rails

I want to change the subject of mail according to actions(create, update), that call the mailer. How to do this? (ex. during creation, subject is User created and for update , user updated)
def create
#user = User.new(params[:user])
#user.save
Mailer.notify(#user).deliver
end
def update
#user = User.find(params[:id])
#user.update
Mailer.notify(#user).deliver
end
mailers.rb
def notify(user)
#user =user
mail(:to =>#use.mail :subject => "created")
end

# controller
def create
#user = User.create(params[:user])
Mailer.notify(#user, 'created').deliver
end
def update
#user = User.find(params[:id])
#user.update
Mailer.notify(#user, 'updated').deliver
end
# mailers.rb
def notify(user, action_name)
#user = user
mail(:to => #user.mail, :subject => "User #{action_name}")
end

You can get the name of the calling method by using
caller_locations(1)[0].label
Example:
def bar
caller_locations(1)[0].label
end
def foo
bar
end
foo # => "foo"

Related

ActiveModel::ForbiddenAttributesError in UserController#register

Im trying to register users on my rails site. When I click the register button on the register page this is what shows up:
ActiveModel::ForbiddenAttributesError in UserController#register
ActiveModel::ForbiddenAttributesError
Here is the code for my user_controller.rb file:
class UserController < ApplicationController
def index
#title = "RailsSpace User Hub"
end
def register
#title = "Register"
if request.post? and params[:user]
#user = User.new(params[:user])
end
if #user.save
flash[:notice] = "User #{#user.screen_name} created!"
redirect_to :action => "index"
end
end
end
It's complaining about line 11: #user = User.new(params[:user]) Im following code from a book so I dont know what's wrong with it.
Does anyone have any suggestions? Thanks for all your help in advance.
You should use strong parameters.
The UserController should look like this:
class UserController < ApplicationController
def index
#title = "RailsSpace User Hub"
end
def register
#title = "Register"
if request.post? and params[:user]
#user = User.new(user_params)
end
if #user.save
flash[:notice] = "User #{#user.screen_name} created!"
redirect_to :action => "index"
end
end
private
def user_params
# Add the user attributes that you sent with post (form) to the permit method.
params.require(:user).permit(:name, :screen_name)
end
end

Rails how to require the current password to allow user update

I am having a rather difficult problem i want to update the user profile only if they submit the current password.I am not using devise.And another post here at stack overflow didn't really help me.
This is my User controller code:
class UsersController < ApplicationController
def new
#user = User.new
end
def show
#user = User.find(params[:id])
#user_posts = #user.posts if #user
if #user
if #user_posts
render 'show.html'
else
render 'show.html'
end
else
render file: 'public/404.html', status: 404, formats: [:html]
end
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to root_path
flash[:notice] = "Successfully Signed up :-)"
else
redirect_to signup_path
flash[:notice] = "You didn't sign up successfully :-("
end
end
def edit
#user = User.find(params[:id])
if current_user.id = #user.id
render 'edit'
else
redirect_to #user
end
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:notice] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
:password == :password_confirmation
private
def user_params
params.require(:user).permit(:user_name, :email, :password, :password_confirmation)
end
end
And this is my user.rb:
class User
has_secure_password
has_many :posts
has_many :comments
def admin?
self.role == 'admin'
end
def moderator?
self.role == 'moderator'
end
end
Please help because I have been working with this for a long time now. And the other solution about this topic here at stack overflow didn't work.
One way is to use virtual attributes
1. The User model
class User < ActiveRecord::Base
attr_accessor :current_password
end
2. The form
add the current_password attribute to the form as a text_field input
3. The UsersController
def update
#user = User.find params[:id]
if #user.authenticate(update_params[:current_password])
# update the user
# maybe check if the data are valid
#user.update(update_params)
else
flash[:warning] = "Please provide your password"
#user.errors.add :current_password, "invalid"
render :edit
end
end
def update_params
params.require(:user).permit(:current_password, :email)
end
First, you have a problem in your edit action:
current_user.id = #user.id
That assigns #user.id to current_user.id - you wanted == to test that it's the correct User. You should put a similar check on update, and probably extract it into a before_action so you can easily apply it anywhere you want to.
To check that the password is present, add it to your form like any other field and then get it out of params to verify it. That would look something like this:
class UsersController < ApplicationController
def update
encrypted = encrypt(params[:password]) # Using whatever your mechanism is
if encrypted == #user.encrypted_password
# Update the user
else
flash[:notice] = 'Password is required to update user information.'
redirect_to edit_user(path(#user))
end
end
end

Send mail at particular time in action mailer using delayed job

def time_confirmation(user)
#user = user
if(#time == (Time.now()))
mail(:to => user.email)
end
end
Is this right? Mail has to be sent at current time.
On your controller do something like:
def create
#user = User.create(user_params)
DelayedEmailJob.new(#user.email).enqueue(wait: 30.minutes)
redirect_to root_path
end

Why is this Mailer giving an error after applying validations?

The error is coming in the create method user mailer section.
I am trying to resolve it, but nothing happens.
How can it be resolved? I come when I apply the validations.
The error is: Expected a URI like gid://app/Person/1234: #<URI::GID gid://email>
My mailer controller:
class UserMailer < ApplicationMailer
def welcome_email(user)
#user = user
#url = 'http:3000//example.com/login#u'
mail(to: #user.email, subject: 'Welcome to My Awesome Site')
end
end
My user controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
#user.save
UserMailer.welcome_email(#user).deliver_later[here the error come about the invalid url]
render 'token'
end
def verify
#user = User.authenticate(params[:auth_token])
if #user
redirect_to edit_user_path(#user)
else
flash.now.alert = "Invalid email or password"
render 'token', :alert =>"Invalid email or password"
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update(user_params)
redirect_to new_login_path
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :dob, :email,
:password, :confirm_password, :auth_token)
end
end
You are trying to pass the Mailer an unpersisted object, ie. an object that was not saved to the database.
From your code, that means that the previous #user.save statement failed probably due to a validation error. In that case, you don't want to send the email anyway.
Change your create action like this:
def create
#user = User.new(user_params)
if #user.save
UserMailer.welcome_email(#user).deliver_later
render 'token'
else
flash[:error] = 'User was not saved'
render 'new'
end
end

Rails- Loading user's page 'Couldn't find User with id=id'

What I am trying to do is to go to user's page after signin/up. On the error page is written that the error is in users_controller. So this is my user controller:
class UsersController < ApplicationController
def show
#user = User.find([:id])
end
def index
end
def new
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
# Handle a successful save.
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
end
Your show method should be:
def show
#user = User.find( params[:id] )
end
And not [:id] alone. You're accessing the :id key at the params hash object.

Resources