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
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
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.
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.
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.
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