Rails devise undefined method `after_sign_in_path_for' - ruby-on-rails

I have controller
class SessionsController < Devise::SessionsController
respond_to :js
layout false
def create
self.resource = warden.authenticate(auth_options)
if resource && resource.active_for_authentication?
sign_in(resource_name, resource)
end
end
end
and my template for it
create.js.erb
<% if user_signed_in?%>
<%= after_sign_in_path_for(resource) %>
<% else %>
Erorrs here...
})
<% end %>
I want redirect to specific page after sign in but have got
NoMethodError - undefined method `after_sign_in_path_for' for #<#<Class
what should i do to fix it?
Rails.application.routes.draw do
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks",:confirmations => "confirmations",:passwords => "passwords", :sessions => "sessions" }
end

I have a similar implementation can you try this
class Devise::SessionsController < DeviseController
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
def create
self.resource = warden.authenticate(auth_options)
if resource && resource.active_for_authentication?
sign_in(resource_name, resource)
end
respond_with resource, :location => after_sign_in_path_for(resource)
end
end
In ApplicationController
private
def after_sign_in_path_for(resource)
stored_location_for(resource) || request.referer || root_path
end

Related

Devise error "undefined local variable or method `resource_class' "

I have the same problem as here undefined local variable or method `resource_class' in devise . The issue is that the code was already set like the answers. Is it a route problem ? Should I look elsewhere?
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :set_locale
before_action :set_instances
before_action :configure_permitted_parameters, if: :devise_controller?
before_action :mixpanel
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
def redirect_to_back
begin
redirect_to :back
rescue ActionController::RedirectBackError => e
redirect_to root_path
end
end
def set_instances
#new_event ||= Event.new(title: ".......", capacity: 50, start_date: Time.zone.now, start_time: Time.zone.now, end_time: Time.zone.now)
#featured_quizz ||= Questionnaire.where('featured IS TRUE')
end
helper_method :resource_name, :resource, :devise_mapping
protected
def resource_name
:user
end
def resource
#resource ||= User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << [:name, :firstname, :lastname, :phone]
devise_parameter_sanitizer.for(:account_update) << [:name, :firstname, :lastname, :image, :phone]
end
end
=> _links.html.slim
.row.text-center
.col-md-10.col-md-offset-1
- if devise_mapping.omniauthable?
- resource_class.omniauth_providers.each do |provider|
= link_to omniauth_authorize_path(resource_name, provider), class:"btn btn-fb btn-block callout callout-fb"
span.fa.fa-facebook-official<>
span Connectez vous avec #{provider.to_s.titleize}
undefined method `users_path' for #<#:0x007ff25695fce0>
Is it a syntax error in front ?
li = link_to "Votre Compte", resource, as: resource_name, url: session_path(resource_name), remote: true, data: { toggle: "modal", target: "#login-modal" }
or is it the block in my routes.rb =>
devise_for :users, :controllers => {
:registrations => "registrations",
:sessions => "sessions",
:confirmations => "confirmations",
:omniauth_callbacks => "callbacks" }
devise_for :admins
Thanks for your help
I don't think the problem is devise related : the Devise Readme makes no mention of creating routes for the model used in devise_for
the users_path helper method is enabled from config/routes.rb with the line :
get '/users', to: 'users#index', as: :users
or shortly, since you will probably need more routes :
resources :users, only: [:index] # you can skip the :only parameter if you need all restful routes.
Check Rails Routing from the Outside In for more information.

How to redirect Devise on sign up and authentication failure?

What i want is if somebody enter wrong information when signing up or signing in to be redirected to a different page other than default let's say mycontroller#index
In my application i'm already overidding Devise::SessionsController and Devise::RegistrationsController.I followed the steps from this link Devise redirect after login fail
But still i get redirected to signup page and signin page. I am using Rails 3.2 and Devise 3.4.1
Here is my code....What am i doing wrong or missing?Thank you in advance.
Session controller
class SessionsController < Devise::SessionsController
def create
resource = warden.authenticate!(:scope => resource_name, :recall => "# {controller_path}#failure")
sign_in_and_redirect(resource_name, resource)
end
def sign_in_and_redirect(resource_or_scope, resource=nil)
scope = Devise::Mapping.find_scope!(resource_or_scope)
resource ||= resource_or_scope
sign_in(scope, resource) unless warden.user(scope) == resource
return render :json => {:success => true}
end
def failure
return render :json => {:success => false, :errors => ["Login failed."]}
end
end
Registrations controller
class RegistrationsController < Devise::RegistrationsController
def create
build_resource
if resource.save
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_up(resource_name, resource)
return render :json => {:success => true}
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
expire_session_data_after_sign_in!
return render :json => {:success => true}
end
else
clean_up_passwords resource
return render :json => {:success => false}
redirect_to {:controller=>"deal",:action=>"confirm_and_pay"}
end
end
def sign_up(resource_name, resource)
sign_in(resource_name, resource)
end
end
Routes
devise_for :users, :skip => [:registrations, :sessions]
devise_scope :user do
get 'signup' => 'devise/registrations#new', :as => :new_user_registration
post 'signup' => 'devise/registrations#create', :as => :user_registration
get 'users/cancel' => 'devise/registrations#cancel', :as => :cancel_user_registration
get 'users/edit' => 'devise/registrations#edit', :as => :edit_user_registration
put 'users' => 'devise/registrations#update'
delete 'users/cancel' => 'devise/registrations#destroy' ,:as=>:destroy_user_session
get 'signin' => 'devise/sessions#new', :as => :new_user_session
post 'signin' => 'devise/sessions#create', :as => :user_session
get 'signout' => 'devise/sessions#destroy', :as => :destroy_user_session
end
Application controller
class ApplicationController < ActionController::Base
protect_from_forgery
def after_sign_up_path_for(resource)
show_deals_path(resource)
end
def after_sign_in_path_for(resource)
sign_in_url = url_for(:action => 'new', :controller => 'sessions', :only_path => false, :protocol => 'http')
if request.referer == sign_in_url
super
else
stored_location_for(resource) || request.referer || root_path
end
end
end
lib/custom_failure.rb
class CustomFailure < Devise::FailureApp
def redirect_url
redirect_to {:controller=>"mycontroller",:action=>"index"}
end
def respond
if http_auth?
http_auth
else
redirect
end
end
end
application.rb
config.autoload_paths += %W(#{config.root}/lib)
If you want to follow Devise redirect after login fail link, you should add this into config/initializers/devise.rb
config.warden do |manager|
manager.failure_app = CustomFailure
end

Rails call controller action on successful object save

I have a user sign up form generated by devise. When the form is submitted and the user object is saved to the database I would like to create and save another object, generated in a separate controller (leads_controller.rb) and pass the user object that was just saved. The sign up form is collecting email, password and password confirmation.
Once the user is saved, I need to pass that user object to the leads_controller to call the new and create actions.
leads_controller.rb
class LeadsController < ApplicationController
include Databasedotcom::Rails::Controller
def new
#lead = Lead.new
end
def create
lead = Lead.new(params[:lead])
lead.Email = #user.email
end
end
routes.rb
# User route
devise_for :users
devise_for :lenders, skip: :sessions, :controllers => {:registrations => "lenders/registrations"}
devise_for :businesses, skip: :sessions
root :to => 'business_account#dashboard', :constraints => lambda { |request| request.env['warden'].user.class.name == 'Business' }, :as => "business_root"
root :to => 'lender_account#dashboard', :constraints => lambda { |request| request.env['warden'].user.class.name == 'Lender' }, :as => "lender_root"
# Leads route
resources :leads
registrations_controller.rb
class Lenders::RegistrationsController < Devise::RegistrationsController
before_filter :update_sanitized_params
def new
super
end
def create
super
end
def update
super
end
private
def update_sanitized_params
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, :type)}
end
end
Is there an action I can put in my registrations_controller.rb to pass the user object to leads_controller.rb?
Copy the content from
https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb
and paste into registrations_controller.rb
Change routes.rb
# User route
devise_for :users, :controllers => { :registrations => "registrations" }
devise_for :businesses, skip: :sessions
root :to => 'business_account#dashboard', :constraints => lambda { |request| request.env['warden'].user.class.name == 'Business' }, :as => "business_root"
root :to => 'lender_account#dashboard', :constraints => lambda { |request| request.env['warden'].user.class.name == 'Lender' }, :as => "lender_root"
# Leads route
resources :leads
In registration_controller.rb change the create action as
NOTE:- see also the change in create action
def create
build_resource(sign_up_params)
resource_saved = resource.save
yield resource if block_given?
if resource_saved
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)
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
In registration_controller.rb
def after_sign_up_path_for(resource)
redirect_to new_lead_path
#after_sign_in_path_for(resource)
end
Devise provide a helper method current_user by which you can know user object in leads_controller.rb and also in views
class LeadsController < ApplicationController
include Databasedotcom::Rails::Controller
def new
#lead = Lead.new
end
def create
lead = Lead.new(params[:lead])
lead.email = current_user.email
end
end

Devise: creating extra records on user creation

How do I create extra records when a user creates an account with devise?
Using a HABTM association between a User and Team model, I'm trying create a team that the user is associated with on there account creation.
Below is the code that I have attempted to use.
class RegistrationsController < Devise::RegistrationsController
def create
super
current_user.teams.create(:name => 'User Name')
end
end
I have also tried this
class RegistrationsController < Devise::RegistrationsController
def create
build_resource
if resource.save
resource.teams.create(:name => 'User Name')
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_in(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_with resource
end
end
end
I solved this by changing routes.rb to point to the customised controller.
routes.rb
devise_for :users,
:controllers => { :registrations => "registrations" }
registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def create
super
resource.teams.create(:name => 'User Name')
end
end
You can use a before_save in your model like this :
class User < ActiveRecord::Base
# ... your code ...
after_create :set_user_on_team
# ... your code ...
private
def set_user_on_team
teams.create(:name => username)
end
end
See the doc here : http://guides.rubyonrails.org/active_record_validations_callbacks.html#available-callbacks

Override method of UsersController in Clearance

I want to change the
def url_after_create
'/'
end
of UsersController in Clearance. If I do this:
class UsersController < Clearance::UsersController
protected
def url_after_create
'/dashboard'
end
end
When I'm trying to sign up a new user, which works perfectly when not overriding, I get the following: The action 'index' could not be found for UsersController -- The action (post) is to '/users' and it seems that since the index action is not defined it fails. What should I do?
EDIT: Added code of Clearance::UsersController
class Clearance::UsersController < ApplicationController
unloadable
skip_before_filter :authorize, :only => [:new, :create]
before_filter :redirect_to_root, :only => [:new, :create], :if => :signed_in?
def new
#user = ::User.new(params[:user])
render :template => 'users/new'
end
def create
#user = ::User.new(params[:user])
if #user.save
sign_in(#user)
redirect_back_or(url_after_create)
else
flash_failure_after_create
render :template => 'users/new'
end
end
private
def flash_failure_after_create
flash.now[:notice] = translate(:bad_email_or_password,
:scope => [:clearance, :controllers, :passwords],
:default => "Must be a valid email address. Password can't be blank.")
end
def url_after_create
'/'
end
end
This line match ':controller(/:action(/:id(.:format)))' located in routes was causing the trouble. Commenting that solved it.

Resources