I create new user. After creating should received confirmation mail. but when i open mailcatcher(http://127.0.0.1:1080/)... nothing!
i use mailcatcher v. 0.5.12, Rails 3.2.22
In development.rb added:
# Don't care if the mailer can't send
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 }
config.action_mailer.raise_delivery_errors = true
What is wrong with settings? How check error? Please, help, thank you.
UPDATE
Confirmationcontroller:
class ConfirmationsController < Devise::ConfirmationsController
def new
super
resource.login = current_user.email if user_signed_in?
end
protected
def after_resending_confirmation_instructions_path_for(resource_name)
if user_signed_in?
home_path
else
new_session_path(resource_name)
end if is_navigational_format?
end
# The path used after confirmation.
def after_confirmation_path_for(resource_name, resource)
'/profile'
end
end
userscontrollers.rb:
# encoding: utf-8
class UsersController < ApplicationController
before_filter :require_admin, only: [:add_moderator, :remove_moderator, :destroy]
before_filter :require_moderator, only: [:edit, :update, :paid_on, :paid_off,
:ban, :unban]
before_filter :authenticate_user!, except: [:new, :create]
before_filter :load_user, only: [:show, :photos, :videos, :audios,
:buy_rating, :do_buy_rating,
:add_moderator, :remove_moderator,
:edit, :update, :paid_on, :paid_off, :ban, :unban, :destroy,
:add_funds, :mute, :unmute]
layout :determine_layout
def new
#user = User.new
#invite = Invite.find_by_code(session[:invite]) if session[:invite].present?
#user.email = #invite.email if #invite
end
def create
#user = User.new(params[:user])
raise ActiveRecord::RecordInvalid.new(#user) unless verify_recaptcha(model: #user, message: 'message')
#invite = Invite.find_by_code(session[:invite]) if session[:invite].present?
User.transaction do
#user.save!
#user.current_password = #user.password
#user.theme_ids = params[:user][:theme_ids]
#user.group_ids = [114, 130]
#user.save!
end
if #invite
#invite.new_user = #user
#invite.use!
end
redirect_to #user
rescue ActiveRecord::RecordInvalid
render :new
end
.........................................................
.........................................................
private
def determine_layout
return 'welcome' if %w(new create).include?(params[:action])
return 'dating' if params[:action]=='search'
'inner'
end
end
registrationscontroller.rb:
# encoding: utf-8
class RegistrationsController < Devise::RegistrationsController
def create
if verify_recaptcha
super
else
flash.delete :recaptcha_error
build_resource
resource.valid?
resource.errors.add(:base, :invalid_recaptcha)
# clean_up_passwords(resource)
render :new
end
rescue ActiveRecord::RecordNotUnique
render :new
end
def update
redirect_to '/settings'
end
# def update
# # required for settings form to submit when password is left blank
# if params[:user][:password].blank?
# params[:user].delete("password")
# params[:user].delete("current_password")
# end
#
# #user = User.find(current_user.id)
# if update_user
# set_flash_message :notice, :updated
# # Sign in the user bypassing validation in case his password changed
# sign_in #user, :bypass => true
# redirect_to after_update_path_for(#user)
# else
# render "edit"
# end
# end
def edit
redirect_to '/settings'
end
def destroy
current_password = params[:user].delete(:current_password)
if resource.valid_password?(current_password)
resource.mark_as_deleted!
render inline: "$('body').fadeOut(3000, function() { document.location = 'http://ya.ru'; })"
else
render inline: "$.flash.error('error')"
end
# Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
# set_flash_message :notice, :destroyed if is_navigational_format?
# respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
end
protected
def after_sign_up_path_for(resource)
'/profile'
end
end
Code was without Devise.mail_confirmation_instructions(#user).deliver. I realized, now all in fine
Related
I use Rails 4, and have four methods at my application_controller.rb for setting flash messages in Rails
def exclusion_info_for model_name
flash[:notice] = "#{model_name.to_s.capitalize} has been deleted."
end
def creation_notice_for model_name
flash[:notice] = "#{model_name.to_s.capitalize} has been created."
end
def update_notice_for model_name
flash[:notice] = "#{model_name.to_s.capitalize} has been updated."
end
def error_notice
flash[:error] = "An unexpected error has it occurred"
end
But the flash setting at exclusion_notice_for is lost after redirection of the action destroy. The others methods works normally.
The Controller
class CustomersController < ApplicationController
respond_to :html
def new
respond_with #customer = customer
end
def create
if #customer = Customer.create(customer_attrs)
creation_notice_for :customer
else
error_notice
end
respond_with #customer, location: "/"
end
def show
respond_with #customer = customer
end
def index
respond_with #customers = Customer.all
end
def edit
respond_with #customer = customer
end
def update
if #customer = customer.update(customer_attrs)
update_notice_for :customer
else
error_notice
end
respond_with #customer, location: "/"
end
def destroy
if #customer = customer.destroy()
exclusion_info_for :customer
else
error_notice
end
respond_with #customer, location: "/"
end
private
def customer
id ? Customer.find(id) : Customer.new
end
def customer_attrs
params.require(:customer).permit(:name)
end
end
This is the application destroy button currently genereted
This is the application.rb file
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :null_session
# protect_from_forgery with: :exception
include FormattedTime
def form_parent
ObjectSpace._id2ref(params[:form_parent_object_id].to_i) if params[:form_parent_object_id]
end
helper_method :form_parent
def root
render "layouts/application", layout: false
end
protected
def id
params[:id]
end
# refactored
def info_flashed model_name, action
flash[:notice] = "#{model_name.to_s.capitalize} has been #{action}."
end
def error_notice
flash[:error] = "An unexpected error has it occurred"
end
end
Flashing Method will work all of your actions simply add 'created' or 'updated' string like in destroy method.
You had error Can't verify CSRF token authenticity
You can put this method in application.rb file to fix it all.
protect_from_forgery with: :exception, if: Proc.new { |c| c.request.format != 'application/json' }
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
protected
def info_flashed (model_name, action)
flash[:notice] = "#{model_name.to_s.capitalize} has been #{action}."
end
In Controller
def destroy
if #customer = customer.destroy
info_flashed (#customer, 'deleted')
else
error_notice
end
respond_with #customer, location: "/" # you need to redirect correct path.
end
I want to create multi user application. Admin user can create new users. how can i do this using devise. Because when after login as admin user i want add new user devise show error that "you are already signed in". How i do this using devise.
I was able to create the Admin User and logged in
User-Controller
class UsersController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def edit
#user = User.find(params[:id])
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = "Successfully created User."
redirect_to root_path
else
render :action => 'new'
end
end
def user_params
params.require(:user).permit(:email, :username, :password, :password_confirmation,:propic)
end
end
Admin Controller
class ClientsController < ApplicationController
skip_before_filter :authenticate_user!, only: [:index, :new, :create]
def new
#client = Client.new
#client.build_owner
render layout: 'sign'
end
def index
#clients = Client.all
render layout: 'welcome'
end
def create
#client = Client.new(client_params)
if #client.valid? then
Apartment::Tenant.create(#client.subdomain)
Apartment::Tenant.switch(#client.subdomain)
#client.save
redirect_to new_user_session_url(subdomain: #client.subdomain)
else
render action: 'new'
end
end
private
def client_params
params.require(:client).permit(:name, :subdomain, owner_attributes: [:email, :username, :password, :password_confirmation,:propic])
end
end
Application Controller
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :load_tenant
before_filter :authenticate_user!
#rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
private
def record_not_found
render 'record_not_found'
end
def load_tenant
Apartment::Tenant.switch(nil)
return unless request.subdomain.present?
client = Client.find_by(subdomain: request.subdomain)
if client then
Apartment::Tenant.switch(request.subdomain)
else
redirect_to root_url(subdomain: false)
end
end
def after_signout_path_for(resource_or_scope)
new_user_session_path
end
end
Anyone? I am super new to Ruby on Rails. All the code is the result of hefty trial and errors.
Ruby on Rails 3.2
My SessionsHelper is working for one of my models but not the other. I cannot figure out the problem. I get his error:
NameError (undefined local variable or method `distributor' for #<DistributorsController:0x00000005357c58>):
app/helpers/sessions_helper.rb:55:in `current_distributor'
app/helpers/sessions_helper.rb:59:in `current_distributor?'
app/controllers/distributors_controller.rb:138:in `correct_distributor'
These are all defined in my helper. My ApplicationController has include SessionsHelper .What is the problem?
This is part of my helper:
def sign_in_distributor(distributor)
cookies[:remember_token] = distributor.remember_token
self.current_distributor = distributor
end
def signed_in_distributor?
!current_distributor.nil?
end
def current_distributor=(distributor)
#current_distributor = distributor
end
def current_distributor
#current_distributor ||= distributor.find_by_remember_token(cookies[:remember_token])
end
def current_distributor?(distributor)
distributor == current_distributor
end
def sign_out_distributor
self.current_distributor = nil
cookies.delete(:remember_token)
end
def admin_distributor
redirect_to(current_distributor) unless current_distributor.admin?
end
def admin_distributor?
current_distributor.admin?
end
This is my controller:
class DistributorsController < ApplicationController
before_filter :signed_in_grandstreamer, only: [:edit, :update, :show, :index]
before_filter :correct_distributor, only: [:edit, :update, :show, :change_password]
before_filter :admin_distributor, only: [:index, :new, :edit, :destroy]
def index
#distributors = Distributor.paginate(page: params[:page])
redirect_to root_url
end
def new
if signed_in_distributor?
redirect_to distributor_path(current_distributor)
elsif signed_in_grandstreamer?
redirect_to grandstreamer_path(current_grandstreamer)
else
#distributor = Distributor.new
end
end
def show
##distributor = Distributor.find(params[:id])
end
...skipping some...
private
def signed_in_grandstreamer
unless signed_in_grandstreamer?
store_location
redirect_to signin_url, notice: "Please sign in." unless signed_in_grandstreamer?
end
end
def signed_in_distributor
unless signed_in_distributor?
store_location
redirect_to signin_url, notice: "Please sign in." unless signed_in_distributor?
end
end
def correct_distributor
#distributor = Distributor.find(params[:id])
##user = User.find(current_user.id)
#checkuser = Distributor.find(params[:id])
redirect_to(current_distributor) unless current_distributor?(#checkuser) || admin_distributor?
end
end
I think you need to change this helper:
def current_distributor
#current_distributor ||= distributor.find_by_remember_token(cookies[:remember_token])
end
To:
def current_distributor
#current_distributor ||= Distributor.find_by_remember_token(cookies[:remember_token])
end
Using CamelCase for class name.
Try changing
distributor.find_by_remember_token(cookies[:remember_token])
To this
Distributor.find_by_remember_token(cookies[:remember_token])
I want to create a custom confirmation method upon sign up built on top of Devise Signup
I'm following the guidelines of this post and this is my Registration Controller, overwritten:
class RegistrationsController < Devise::RegistrationsController
skip_before_filter :require_no_authentication, :only => [ :create, :edit, :update, :create_by_user ]
# before_filter :configure_permitted_parameters, if: :devise_controller?
def new
super
end
def create
build_resource(sign_up_params)
puts "what is resource_name: #{resource_name}"
resource.confirmed ||= false
resource.confirmation_code ||= create_random_pass
if resource.save
yield resource if block_given?
if resource.active_for_authentication?
# set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
respond_with resource, :location => after_sign_up_path_for(resource)
UserMailer.send_simple_message(resource).deliver
else
# set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
expire_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
respond_with resource
end
end
def edit
super
end
def update
super
end
def confirmation
#user = User.find(params[:user_id])
end
def confirm
## handles the confirmation
puts "The params: #{params[:confirmation_code]}"
puts "Hello"
user = User.find(params[:user_id])
if user.confirmed == false
puts "It's false"
redirect_to '/'
elsif user.confirmed == true
puts "It's true"
else
puts "It's nil"
end
end
and I match the routes such as:
devise_scope :user do
root to: 'static_pages#home'
match '/sessions/user', to: 'devise/sessions#create', via: :post
match '/users/newuser', to: 'registrations#create_by_user', via:[:post, :get]
match '/users/:user_id/confirmation/', to: 'registrations#confirmation', via: :get
match '/users/:user_id/confirm', to: 'registrations#confirm', via: :post
end
when I submit the form in '/users/:user_id/confirmation' I get an error:
NameError in UsersController#update
undefined local variable or method `signed_in_user' for #<UsersController:0x00000005696e00>
I clearly don't fully understand what devise is doing, because I don't get why he calls the Users controller instead of Registration Controller
EDIT:
My UsersController:
class UsersController < ApplicationController
before_action :signed_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }
def show
#user = User.find(params[:id])
end
def new
#user = User.new
3.times { #user.accounts.build }
end
def create
# #user = params[:user] ? User.new(user_params) : User.new_guest
#user = User.new(user_params)
#account = #user.accounts.new(account_params)
if #user.save && #account.save
sign_in #user
##flash[:success] = "Welcome to the HighTide!"
redirect_to #user
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
#flash[:success] = "Profile updated"
sign_in #user
redirect_to #user
else
render 'edit'
end
end
## I tried also putting in here the logic of the confirmation code
def confirmation
#user = User.find(params[:user_id])
end
def confirm
puts "The params: #{params[:confirmation_code]}"
puts "Hello"
# self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
# prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
user = User.find(params[:user_id])
if user.confirmed == false
puts "It's false"
redirect_to '/'
elsif user.confirmed == true
puts "It's true"
else
puts "It's nil"
end
end
private
def correct_user
#user = User.find(params[:id])
redirect_to(root_path) unless current_user?(#user)
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
def user_params
# params.require(:user).permit(:name, :email, :password,
# :password_confirmation, accounts_attributes: [:id, :title])
params.fetch(:user, {}).permit(:name, :email, :password,
:password_confirmation, accounts_attributes: [:id, :title])
end
end
Use authenticate_user instead of signed_in_user. This is required for devise configuration.
You have a before action call in users controller. That expects a method called signed_in_user. Why do you have that there? This got nothing to do with devise.
How do I do RESTful sign-up and sign-in using devise in Ruby on Rails (I am using version 4)?
I could not find any documentation with regards to the parameters (e.g. email, password) that I should POST to the server.
It seems that RESTful login using JSON data (e.g. via AJAX) is not supported out of the box in the current version of devise - the default behavior is to send back a whole HTML page for any type of request made, instead of a JSON object for handling JSON request specifically.
Does this mean that I need to create/extend custom controller for handling user registration and login for RESTful apps using JSON? If so, please elaborate.
If you're using Devise, all of the RESTful actions have been provided through their forms & controller (if you browse to http://your-app.com/users/sign_up, you'll be able to register etc)
If you're looking to make your Devise handle JSON, you are correct in that it's not handled "out of the box", but fortunately, there is a way to do it:
Live Code
#config/routes (notice custom controllers)
devise_for :users, :path => '', :controllers => {:sessions => 'sessions', :registrations => 'registrations'}
#app/controllers/registrations_controller.rb
class RegistrationsController < DeviseController
prepend_before_filter :require_no_authentication, :only => [ :new, :create, :cancel ]
prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]
before_filter :configure_permitted_parameters
prepend_view_path 'app/views/devise'
# GET /resource/sign_up
def new
build_resource({})
respond_with self.resource
end
# POST /resource
def create
build_resource(sign_up_params)
if resource.save
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_up(resource_name, resource)
respond_with resource, :location => after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
respond_to do |format|
format.json { render :json => resource.errors, :status => :unprocessable_entity }
format.html { respond_with resource }
end
end
end
# GET /resource/edit
def edit
render :edit
end
# PUT /resource
# We need to use a copy of the resource because we don't want to change
# the current user in place.
def update
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
if update_resource(resource, account_update_params)
if is_navigational_format?
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
:update_needs_confirmation : :updated
set_flash_message :notice, flash_key
end
sign_in resource_name, resource, :bypass => true
respond_with resource, :location => after_update_path_for(resource)
else
clean_up_passwords resource
respond_with resource
end
end
# DELETE /resource
def destroy
resource.destroy
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
set_flash_message :notice, :destroyed if is_navigational_format?
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
def cancel
expire_session_data_after_sign_in!
redirect_to new_registration_path(resource_name)
end
protected
# Custom Fields
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:first_name, :last_name,
:email, :password, :password_confirmation)
end
end
def update_needs_confirmation?(resource, previous)
resource.respond_to?(:pending_reconfirmation?) &&
resource.pending_reconfirmation? &&
previous != resource.unconfirmed_email
end
# By default we want to require a password checks on update.
# You can overwrite this method in your own RegistrationsController.
def update_resource(resource, params)
resource.update_with_password(params)
end
# Build a devise resource passing in the session. Useful to move
# temporary session data to the newly created user.
def build_resource(hash=nil)
self.resource = resource_class.new_with_session(hash || {}, session)
end
# Signs in a user on sign up. You can overwrite this method in your own
# RegistrationsController.
def sign_up(resource_name, resource)
sign_in(resource_name, resource)
end
# The path used after sign up. You need to overwrite this method
# in your own RegistrationsController.
def after_sign_up_path_for(resource)
after_sign_in_path_for(resource)
end
# The path used after sign up for inactive accounts. You need to overwrite
# this method in your own RegistrationsController.
def after_inactive_sign_up_path_for(resource)
respond_to?(:root_path) ? root_path : "/"
end
# The default url to be used after updating a resource. You need to overwrite
# this method in your own RegistrationsController.
def after_update_path_for(resource)
signed_in_root_path(resource)
end
# Authenticates the current scope and gets the current resource from the session.
def authenticate_scope!
send(:"authenticate_#{resource_name}!", :force => true)
self.resource = send(:"current_#{resource_name}")
end
def sign_up_params
devise_parameter_sanitizer.sanitize(:sign_up)
end
def account_update_params
devise_parameter_sanitizer.sanitize(:account_update)
end
end
This is probably excessive, but it works (try registering or logging in at http://firststop.herokuapp.com). You could probably achieve the same thing with this code (completely untested):
def create #-> completely untested & speculative
super do |format|
format.json { render :json => resource.errors, :status => :unprocessable_entity }
format.html { respond_with resource }
end
end
Login Code
class SessionsController < DeviseController
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
prepend_before_filter :allow_params_authentication!, :only => :create
prepend_before_filter { request.env["devise.skip_timeout"] = true }
prepend_view_path 'app/views/devise'
# GET /resource/sign_in
def new
self.resource = resource_class.new(sign_in_params)
clean_up_passwords(resource)
respond_with(resource, serialize_options(resource))
end
# POST /resource/sign_in
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_to do |format|
format.json { render :json => {}, :status => :ok }
format.html { respond_with resource, :location => after_sign_in_path_for(resource) }
end
end
# DELETE /resource/sign_out
def destroy
redirect_path = after_sign_out_path_for(resource_name)
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
set_flash_message :notice, :signed_out if signed_out && is_navigational_format?
# We actually need to hardcode this as Rails default responder doesn't
# support returning empty response on GET request
respond_to do |format|
format.all { head :no_content }
format.any(*navigational_formats) { redirect_to redirect_path }
end
end
protected
def sign_in_params
devise_parameter_sanitizer.sanitize(:sign_in)
end
def serialize_options(resource)
methods = resource_class.authentication_keys.dup
methods = methods.keys if methods.is_a?(Hash)
methods << :password if resource.respond_to?(:password)
{ :methods => methods, :only => [:password] }
end
def auth_options
{ :scope => resource_name, :recall => "#{controller_path}#new" }
end
end