Devise Ajax 404 routing error - ruby-on-rails

I am testing ajax with devise and am running into this error in console:
GET https://example.com/users/get_company?foo=bar 404 (Not Found)
and rails server is returning:
ActionController::RoutingError (uninitialized constant UsersController):
A little bit of code:
config/routes.rb
devise_for :users, :controllers => {registrations: 'registrations'}
devise_scope :user do
authenticated :user do
root 'account#show', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
get 'users/get_company', as: 'get_company'
initializers/devise.rb
config.http_authenticatable_on_xhr = true
config.navigational_formats = ['*/*', :html]
controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
respond_to :json
def get_company
#company = Company.first.name
respond_to do |format|
format.js
end
end
end
In views/devise/registrations there is new.html.erb, get_company.js.coffee and in assets/javascripts there is get_company.js.coffee.
These seem to be working fine because the event happens and then I am getting the routing error.
Any help would be greatly appreciated as I am just learning this to help out with a project. Please ask for any additional code or anything that might help explain the situation better.

Hey your route of get_company is missing /, so it would be:
devise_for :users, :controllers => {registrations: 'registrations'}
devise_scope :user do
authenticated :user do
root 'account#show', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
# 1: If you put your get_company route here, it still works
get '/users/get_company' => 'registrations#get_company', as: 'get_company'
end
# 2: If you put your get_company route here, it works as well
# get '/users/get_company' => 'registrations#get_company', as: 'get_company'
You code will work fine either you put the route in position #1 or #2

Related

Ruby on Rails Devise id='sign up'

So a few people have had this problem, but none of their code actually matches mine so their solutions aren't working.
Basically, whenever I try to access /users/:id it passes in the params correctly {'id' => '1'}, but then the page errors out on 'no user with id='sign_out'
My routes:
Rails.application.routes.draw do
devise_for :users, path: 'devise'
get 'sessions/new'
get 'intro', to: 'index#intro'
root 'index#intro'
authenticated :user do
root 'index#homepage', as: :authenticated_root
end
devise_scope :user do
get '/start', to: 'devise/sessions#new', as: "login"
get '/devise/sign_out', to: 'devise/sessions#destroy', as: "logout"
get '/signup', to: 'users#new', as: "signup"
end
get '/forgotPassword', to: 'index#forgotPassword'
get '/homepage', to: 'index#homepage'
get '/meetUs', to: 'index#meetUs'
get '/makeSuggestion', to: 'index#makeSuggestion'
get 'profile', to: 'index#profile'
resources :suggestions
resources :rewards
resources :users
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Code in controller erroring out:
# GET /users/1
# GET /users/1.json
def show
#users = User.find(params[:id])
end
I'm pretty sure the issue has something to do with the routes thinking /users is both a resource of mine and of devise. But I don't know how to tell it to use the default route rails made as opposed to the one devise made.
If anyone could help, and try and explain why it's happening, that'd be great. Thanks in advance!
edit: Picks of the error and trace

You are being redirected. Rails 5 + Devise

My rails application successfully logs out a user and redirects to the about page when in development mode. But the moment i deploy it to production it returns a 302 status and a page that shows "you are being redirected". Am using devise for authentication below is what my code actually looks like.
The routes
Rails.application.routes.draw do
devise_for :users, controllers: { registrations: "users/registrations", confirmations: "users/confirmations", sessions: "devise/sessions" }, skip: [:sessions]
devise_scope :user do
get "login" => "devise/sessions#new", as: :new_user_session
post "login" => "devise/sessions#create", as: :user_session
get "/join" => "users/registrations#new", as: :join
get '/logout', to: "devise/sessions#destroy", as: :destroy_user_session
end
resources :companies
get "/about", to: "pages#about"
get "/faq", to: "pages#faq"
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'pages#home'
end
My application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper
protected
def after_sign_in_path_for(resource)
company_path(resource)
end
def after_sign_out_path_for(resource_or_scope)
"/about"
end
def store_location
session[:return_to] == request.full_path
end
def clear_stored_location
session[:return_to] = nil
end
def redirect_back_or_to(alternate)
redirect_to(session[:return_to] || alternate)
clear_stored_location
end
end
And finally my link to log out.
<%= link_to "Log out", destroy_user_session_path %>
Please note that i am using devise 4.2.0 and capistrano for deployment.
Regards
~
I had to override devise sessions#controller and changed my routes to:
delete 'logout', to: "users/sessions#destroy", as: :destroy_user_session
Then i added delete method to my link for logging out.

Routing Error - uninitialized constant Users::RegistrationsController

I have started on a web application for user registration etc. using devise gem. I am novice to Ruby/Rails env. So this is part of my training.
My question is very similar to an old posting # devise overriding registrations controller - uninitialized constant Users::RegistrationsController
After the homepage displays, when I click on signup button, I get this error. I have done some research on this issue on the web to no avail.
In app/controllers/users/registrations_controllers.rb I have this code:
class Users::RegistrationsController < Device::RegistrationsController
def create
super do |resource|
if params[:plan]
resource.plan_id = params[:plan]
if resource.plan_id == 2
resource.save_with_payment
else
resource.save
end
end
end
end
end
In Routes.rb I have this line of code:
devise_for :users, :controllers => { :registrations => 'users/registrations' }
Please let me know if you need any other information to help resolve this error.
In routes.rb, try:
devise_for :users,
:skip => [:registrations, :sessions]
as user do
# Registrations
get '/signup' => 'users/registrations#new', as: :new_user_registration
post '/signup' => 'users/registrations#create', as: :user_registration
It should work.

ActionController::RoutingError when test custom devise controller

I'm trying to add a custom action to Devise's registration controller which allows users to change their passwords (I cannot use default registrations#edit since I need a form for changing only password, not email/username). The implementation I wrote below works in development mode but I get this error when I test controller.
Failure/Error: get 'password'
ActionController::RoutingError:
No route matches {:controller=>"registrations", :action=>"password"}
There is my code (I tried to skip unrelated parts)
spec/controllers/registrations_controller_spec.rb
describe RegistrationsController do
include Devise::TestHelpers
before :each do
request.env["devise.mapping"] = Devise.mappings[:users]
end
describe "GET 'password'" do
it "..." do
# The problem is here,
get 'password' # it raises ActionController::RoutingError
end
end
end
app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
# ...
def password
end
end
config/routes.rb
devise_for :users, path: 'account',
controllers: { registrations: 'registartions' },
skip: [:registartions, :sessions]
devise_scope :user do
# ...
scope '/account' do
get 'password' => 'devise/registartions#password', as: "change_password
do
end
spec_helper.rb
# ...
RSpec.configure do |config|
# ...
config.include Devise::TestHelpers, :type => :controller
end
I would usually add a comment for this, but I'm including a code block and it gets messy in comments.
It seems like you're trying to preform a GET on /password instead of on /account/password.
From what I'm reading, you've got a mapping for /account/password:
devise_scope :user do # used to remove /users/ part from devise URLs
# ...
scope '/account' do # adds /account to URLs
get 'password' => 'devise/registartions#password', as: "change_password"
# this will match /account/passwordAnswer
do
end
So you should either remove the scope, or replace your get request in test with this:
get "/account/password", :user => #user
or this
get change_password_path(#user)
Where #user is a User's mock.
Run rake routes to confirm.
Have you set up your config/routes.rb with the following.
devise_for :users do
get 'logout' => 'devise/sessions#destroy'
get 'changepassword' => 'devise/registrations#edit'
get 'access' => 'homepages#access'
get 'history' => 'policies#history'
get 'future' => 'policies#future'
end
devise_for :users, :controllers => { :sessions => :sessions }
resources :users
I have the same problem. I set the routes then it was worked for me :)
I don't like using get "/account/password" or a path in my spec. Seems hacky. I fixed a similar problem by using better syntax in my routes.rb file:
Using path: 'account' option in devise_for
Explicitly setting my custom controller with controllers: {registrations: 'registrations'}
So my routes.rb looks like this:
devise_for :users,
path: 'account',
path_names: {sign_in: 'login', sign_out: 'logout', sign_up: 'register'},
controllers: {registrations: 'registrations'},
skip: [:passwords]
Then I can use get :new in my test. Much cleaner.
Hope this helps someone else.
I am using devise 3.0.

Setting Devise Login to be root page

I am using the following code for my routes:
devise_for :user,
:as => '',
:path_names => {
:sign_in => "",
:sign_out => "logout",
:sign_up => "register"
}
But when I'm logged out and I goto /logout I get the following error:
No route matches {:action=>"new",
:controller=>"devise/sessions"}
How do I setup the root path to be to :sign_in action?
To follow on from the people who are asking about the error Could not find devise mapping for path "/" there is a workaround.
You'll find that there is a clue in your logs which will probably say:
[Devise] Could not find devise mapping for path "/".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
match "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
#request.env["devise.mapping"] = Devise.mappings[:user]
So I retried the approach but instead wrapping it (as #miccet suggets) inside a scope block:
devise_scope :user do
root to: "devise/sessions#new"
end
This worked fine for me
devise_for :users
devise_scope :user do
authenticated :user do
root 'home#index', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
Just like this, tested on Rails Rails 4.1.0.rc1.
root :to => "devise/sessions#new"
I needed to set the default home root. I felt like I had tried this all night last night (prior to posting the question), but it's working now. If you're logged out, Devise attempts to redirect you to the root path which I had undefined.
(This was posted as a suggested edit, but should have been an answer of its own. I don't know if it makes sense or not. Dear anonymous editor: feel free to repost this answer as your own, and leave me a comment so I'll delete this copy.)
root :to => redirect("/users/login")
I got this to work with #VvDPzZ answer. But I had to modify it slightly
devise_scope :business_owner do
authenticated do
root to: 'pages#dashboard'
end
unauthenticated do
root to: 'devise/sessions#new', as: 'unauthenticated_root'
end
end
I had to ad to: in the root path declaration. I also removed the as: :authenticated_root because I already had some places in my application referencing root_path in links. By leaving out the as: :authenticated_root part I didn't have to change any of my existing links.
I guess you have different user roles. If you do you have to add a scope like this to the users resource:
devise_scope :user do
get "/logout" => "devise/sessions#destroy"
end
You can read more about overriding devise routes here:
https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes
Some of these solutions are way too complex. Just use Rails:
Add 'get' 'users/root', to: 'users#root' to config/routes.rb.
In UsersController do something like:
def root
if user_signed_in?
redirect_to root_for_signed_in_user_path (or whatever)
else
redirect_to new_user_session_path
end
end
Using rails 3.2 and devise 3.2.3 I manage to setup my home page "home#index" (controller#action) as the login page making the following changes.
#1 Added the login form to the home page:
<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.button :submit %>
<% end %>
#2 Added methods resource_name, resource and devise_mapping to app/heldpers/application_helper.rb:
def resource_name
:user
end
def resource
#resource ||= User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
#3 Created a custom sessions controller app/controllers/users/sessions_controller.rb:
class Users::SessionsController < Devise::SessionsController
protected
# This method tell sessions#create method to redirect to home#index when login fails.
def auth_options
{ scope: resource_name, recall: 'home#index' }
end
end
#4 Skip the session routes and setup the custom sessions controller in config/routes.rb:
devise_for :users, path: 'auth', skip: [:sessions],
controllers: {
sessions: 'users/sessions'
}
as :user do
get 'auth/sign_in' => 'home#index', as: :new_user_session
post 'auth/sign_in' => 'users/sessions#create', as: :user_session
delete 'auth/sign_out' => 'users/sessions#destroy', as: :destroy_user_session
end
I'm new on rails and I didn't know your 'device_scope' name have to be different to your 'device_for' name. Notice my example.
I tried this a hundred times a this is why it didn't work jajaja
devise_for :user_devises, path: 'user_devises'
devise_scope :user_devise do
authenticated :user_devise do
root 'home#index', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end

Resources