Setup devise with custom registration controller - ruby-on-rails

I'm working on a rails site using devise, where we do not want user sign ups just yet. User authentication is so we can login to access restricted parts of the site and add/edit things as we see fit. So for now, I created the following controller:
class Users::RegistrationController < Devise::SessionsController
def new
end
end
And setup my routes in this fashion:
devise_for :users, :controllers => { :registration => "users/registration" }
However, when I run rake routes, I still see a returned value for the create action on the registration controller. Any ideas on how to get rid of it?

Try using :registrations instead of :registration. Also, it seems like your custom controller class should be defined via:
class Users::RegistrationsController < Devise::RegistrationsController

Related

Devise Invitable controller seems not to be reached?

I installed devise-invitable and using the standard devise-invitable controller (which I didn't generate) it functions properly. However, when I tried generating a custom controller for devise-invitable, I encountered some issues. Please find below the steps I took.
Steps I took to generate the controller
Following the documentation of devise I tried generating the invitations controller via the console which failed:
rails generate devise:controllers users -c=invitations
Running via Spring preloader in process 64830
Could not find "invitations_controller.rb" in any of your source paths. Your current source paths are:
/Users/name/code/name/app/lib/templates/devise/controllers
/Users/name/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/devise-4.7.0/lib/generators/templates/controllers
When this didn't work, I manually tried implementing:
a controller in the folder where all other devise controllers were generated
Adding the invitations controller to routes.rb
=> This didn't seem to work either, because I tried breaking the controller to see if it was reached, but it doesn't break.
controllers/users/invitations_controller.rb
class Users::InvitationsController < Devise::InvitationsController
def new
#hotel = Hotel.find(params[:park_id])
#user = User.new
#user.hotel = #hotel
text to cause an error message
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: {
sessions: 'users/invitations'
}
The problem is in your routes since an invitation is not an session.
If you changes sessions to invitations in your routes then it will hit the users/invitations controller.
# routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: {
invitations: 'users/invitations'
}
end

how to overwrite devise controllers?

I have the devise SessionController overwrited:
on app/controllers/customers/sessions_controller.rb
class Customers::SessionsController < Devise::SessionsController
before_filter :destroy_cart, only: :destroy
def destroy_cart
cart = Cart.find(current_client.cart.id)
cart.destroy
end
end
but the cart is never destroyed, even if I overwrite the destroy method directly and add the super after my code, the cart its still there, in the database (I knkow I could create the cart just once and get it when the user logs in again or create a new one when he use the app for first time, but I want to try it this way for now), is like if is not reading my code on that SessionController.
and for some reason even when I have my views this way:
app/views/customer/registrations
the changes that I do on that views are only reflected if I change it to
app/views/devise/registrations
my routes.rb is:
devise_for :clients, :controllers => { sessions: 'customers/sessions'}
devise_scope :client do
root to: "customers/Sessions#new"
end
the model that I am using with devise is Client
why I cant destroy the cart in the devise controller?
and why I cant use the views/customer/sessions if the documentation it says I can/have to do it?
thank you for reading.
you can always try to do
def destroy
cart = Cart.find(current_client.cart.id)
cart.destroy
super
end
but first you might want to ensure that you really overwritten devise's controller correctly.
The reason why you can't see changes done to app/views/customer/registrations is beacuse you seems to overwrite only :sessions controller, so you need to change
devise_for :clients, :controllers => { sessions: 'customers/sessions'}
to
devise_for :clients, :controllers => { registrations: 'customers/registrations', sessions: 'customers/sessions'}
The last question is:
" why I cant use the views/customer/sessions if the documentation it says I can/have to do it? "
You have a typo here, you are using customers namespace, not customer in routes.rb [ sessions: 'customers/sessions' ] - just a typo?
Watch your spelling. The before_filter is calling a method that doesn't exist.

Using Devise Gem with namespaces throwing ActionController::RoutingError

Ok, I've seen a ton of different answers for how to get Devise working when using namespaces in your app, but none of them are working for me.
I have my app split up into three namespaces
Home (the public landing pages)
Account (the logged in profile/account of the user)
Admin (the admin backend which isn't written yet)
I've also split up all the partials into a base folder in each namespace. So each of my controllers inherit from the BaseController which inherits from the ApplicationController:
module Account
class UsersController < BaseController
end
end
And I created a sessions_controller.rb in both account and home that inherits from the devise sessions controller like this:
module Account
class SessionsController < BaseController < Devise::SessionsController
end
end
The goal is to have a login/ registration form in the Home namespace that lets users login to the users controller that is in the account namespace.
Right now when I click on the link generated by:
<%= link_to "register", new_user_registration_path %>
I'm getting
ActionController::RoutingError at /users/sign_up
uninitialized constant Account::RegistrationsController
My routes.rb file looks like this:
scope :module => "account" do
devise_for :users, :controllers => { :sessions => "account/sessions" }
resource :users
end
scope :module => "home" do
resources :home, :about, :jobs, :terms, :privacy, :android_availability, :about, :contact
end
get "home/index"
root :to => 'home::home#index'
end
The home controllers use a home layout and the account controllers use the application layout. I specify layout "home" in the home controllers, but I don't specify layout "application" in the account controllers because application is the default layout rails looks for.
Ok. I think I've covered all my bases. Any idea what I'm doing wrong here?
Thanks!
EDIT:
Ok, I've added a registrations_controller.rb file to the account namespace in the same way as the sessions_controller.rb file described above.
I also updated the routes.rb file:
scope :module => "account" do
devise_for :users, :controllers => {
:sessions => "account/sessions",
:registrations => "account/registrations" }
resource :users
end
Now I'm getting a new error that I don't understand. Here it is:
NoMethodError at /users/sign_up
undefined method `action' for Account::RegistrationsController:Class
It says the undefined method 'action' is in (gem) actionpack-3.2.11/lib/action_dispatch/routing/route_set.rb which doesn't make any sense.
Specifically is says the problem is here:
def dispatch(controller, action, env)
controller.action(action).call(env)
end
EDIT 2:
Here is the code from my registrations_controller.rb
module Account
class RegistrationsController < BaseController < Devise::RegistrationsController
end
end
EDIT 3:
module Account
class BaseController < ApplicationController
end
end
Ok, the above is my base_controller.rb, which just inherits from the ApplicationController. All the other controllers inherit from BaseController. Because I've split my app into three namespaces, the base_controller is there to tell the other controllers in the namespace that the partials are in a folder named base within their namespace. As shown in this RailsCast
I get a missing partial error if I don't incude the BaseController because the devise controllers can't find the partials.
Read your errors! :-)
For starters, looks like you need to define an Account::RegistrationsController, the same way you did your Account::SessionsController.

How to override devise to redirect to a different URL other than the root when user login or register?

I am using devise and I have a root pointing home#index, now I want to override devise when a user register or login to redirect to project#show instead of the root(home#index). What method do I put in the overidden devise controller? Also do I have to add anything in the routes.rb?
Thank you in advance!
class RegistrationsController < Devise::RegistrationsController
end
routes.rb
Parks::Application.routes.draw do
resources :home, :project
devise_for :users
root :to => "home#index"
end
available path
show_project_path
I think the after_sign_in_path_for hook is what you're looking for: http://rdoc.info/github/plataformatec/devise/master/Devise/Controllers/Helpers:after_sign_in_path_for
As you can see from the docs, you can define a route that will automatically be used (by the original implementation of the hook) or you can override it completely.

devise and STI how to login as Base class upon registration

I've seen similar posts already, but couldn't quite get the answer I needed.
I have a User model and using STI a Student model that is a type of User.
When I create a new Student, Devise logs in that Student with a student_session. The problem is the rest of my app uses a user_session. SO, should I create a new user_session using the student_session? and then logout the student?
Or is there a way to get Devise to allow a student creation, but login as the User base model?
Thank you,
Anthony
Check out this post and see if it helps you:
Rails: Using Devise with single table inheritance
The summary is essentially to do the following:
config/routes.rb:
devise_for :users, :controllers => { :sessions => 'sessions' }, :skip => :registrations
devise_for :students, :skip => :sessions
app/controllers/sessions_controller.rb:
class SessionsController < Devise::SessionsController
def create
rtn = super
sign_in(resource.type.underscore, resource.type.constantize.send(:find, resource.id)) unless resource.type.nil?
rtn
end
end
For this you have to create a custom controller.
Just an example implementation
#POST create
def create
student = Student.create(params[:student]) # normal crud with whatever your form params
sign_in(User.find(student.id)) # this actually signs in the user
# now redirect the student to the dash board / whatever page manually
end

Resources