Devise Update method does not have ID in route - ruby-on-rails

I have two models using Devise 3. My edit and update routes do not have the /:id that I would expect and it is causing me to receive a bad PUT requestion as you can see below.
Started PUT "/users.user" for 127.0.0.1 at 2014-06-11 11:11:46 -0400
Processing by RegistrationsController#update as
Completed 406 Not Acceptable in 4894.6ms (ActiveRecord: 2.4ms)
Here are the routes
new_user_session GET /users/sign_in(.:format) sessions#new
user_session POST /users/sign_in(.:format) sessions#create
destroy_user_session DELETE /users/sign_out(.:format) sessions#destroy
user_password POST /users/password(.:format) passwords#create
new_user_password GET /users/password/new(.:format) passwords#new
edit_user_password GET /users/password/edit(.:format) passwords#edit
PUT /users/password(.:format) passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
This is what my routes.rb looks like
devise_for :users, :controllers => { :confirmations => "confirmations", registrations: "registrations", session: "sessions", passwords: "passwords" }
devise_scope :user do
authenticated :user do
root :to => 'appointments#index', as: :user_authenticated_root
get "/appointments", to: "appointments#index", as: :appointments
end
unauthenticated :user do
root :to => 'devise/registrations#new', as: :unauthenticated_root
end
match '/join' => 'devise/registrations#new'
end
My form is
<%= simple_form_for(resource, :as => resource_name, :url => user_registration_path(resource_name)) do |f| %>
<%= f.error_notification %>
What am I missing to fix the routes to say /users/:id(.:format), etc ?

I think this should do it:
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>

Related

How to use Devise both in the site and in the Admin Pages

I'm new to RoR and Devise and i'm stuck in User Authentications with Devise. I'm developing a web site, which has admin pages in it. My structure looks like this:
app
|-controllers
|-admin
|- user_list_controller.rb //Every user crud operations are in it.
|-views
|-admin
|-user_list
|-new.html.erb
|-edit.html.erb
|-devise //Also have devise views
UserListController:
class Admin::UserListController < ApplicationController
layout 'admin/admin'
def index
#user_list = User.all
end
def new
#user = User.new
end
def edit
end
def delete
end
def create_user
end
end
What I want to do is that, I want to use Devise methods under this controller but this is where I stuck in. I created a UserController which base is Devise::RegistrationsController. But this time I got this error,
Could not find devise mapping for path "/admin/create_user". This may
happen for two reasons: 1) You forgot to wrap your route inside the
scope block. For example: devise_scope :user do get "/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]
It looks like a route.rb error and my route file is:
Rails.application.routes.draw do
devise_for :users
devise_scope :user do
# post "admin/add_user" =>"admin/user_list#create_user", as: :adduser
end
namespace :admin do
root to: 'admin#index'
get 'user_list', :to => 'user_list#index'
post 'create_user', :to => "user#create"
get 'new_user', :to => 'user_list#new'
get 'user_proposals', :to => 'user_proposal_forms#index'
get 'user_appointments', :to => 'user_appointments#index'
get 'brands', :to => 'brands#index'
get 'brand_makes', :to => 'brand_makes#index'
get 'make_types', :to => 'make_types#index'
end
end
And the result of rake routes is this:
Prefix Verb URI Pattern Controller#Action new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format)devise/registrations#new edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
admin_root GET /admin(.:format) admin/admin#index
admin_user_list GET /admin/user_list(.:format) admin/user_list#index
admin_create_user POST /admin/create_user(.:format) admin/user#create
admin_new_user GET /admin/new_user(.:format) admin/user_list#new
admin_user_proposalsGET /admin/user_proposals(.:format) admin/user_proposal_forms#index
admin_user_appointments GET /admin/user_appointments(.:format) admin/user_appointments#index
admin_brands GET /admin/brands(.:format) admin/brands#index
admin_brand_makes GET /admin/brand_makes(.:format) admin/brand_makes#index
admin_make_types GET /admin/make_types(.:format) admin/make_types#index
It looks messy, sorry for that. Finally my form_for looks like this:
<%= simple_form_for #user, url: admin_create_user_path, class: "form-horizontal" do |f| %>
<%= render(:partial => "form", :locals => {:f => f}) %>
<% end %>
So where did I make a mistake? I've read all the documents in Devise, tried so many things but couldn't solve the problem.
In routes file use
devise_for :users, :controllers => { registrations: 'registrations' }

Rails 4:Error in setting up SignIn Page as root page using Devise

I am using Devise Gem for authentication but for the index/root page for my application I want to use sign_in page of devise gem.
I have used the following code in the config/routes.rb file
root 'devise/sessions#new'
I am getting the following error
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 get "/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]
Here is snapshot of my rake routes output
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destro
workout_schedules_find POST /workout_schedules/find(.:format) workout_schedules#find
workout_schedules GET /workout_schedules(.:format) workout_schedules#index
POST /workout_schedules(.:format) workout_schedules#create
new_workout_schedule GET /workout_schedules/new(.:format) workout_schedules#new
edit_workout_schedule GET /workout_schedules/:id/edit(.:format) workout_schedules#edit
workout_schedule GET /workout_schedules/:id(.:format) workout_schedules#show
PATCH /workout_schedules/:id(.:format) workout_schedules#update
PUT /workout_schedules/:id(.:format) workout_schedules#update
DELETE /workout_schedules/:id(.:format) workout_schedules#destroy
Try to set your route file like this:
devise_scope :user do
authenticated :user do
root 'home#dashboard', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
Devise provides some inbuilt methods like authenticated, unauthenticated etc. So as per your requirement, you can set different root for logged in users and non-logged in users.
:as will create custom named url helpers like authenticated_root_path and unauthenticated_root_path
If you will run rake routes, you will get:
authenticated_root GET / home#dashboard
unauthenticated_root GET / devise/sessions#new
Here's my working example of how to solve this:
Rails.application.routes.draw do
# This is the fix.
devise_for :users, skip: :all
devise_scope :user do
get "/users/sign_in", to: "devise/sessions#new", as: :new_user_session
post "/users/sign_in", to: "devise/sessions#create", as: :user_session
delete "/users/sign_out", to: "devise/sessions#destroy", as: :destroy_user_session
get "/users/password/new", to: "devise/passwords#new", as: :new_user_password
get "/users/password/edit", to: "devise/passwords#edit", as: :edit_user_password
patch "/users/password", to: "devise/passwords#update", as: :user_password
put "/users/password", to: "devise/passwords#update"
post "/users/password", to: "devise/passwords#create"
get "/users/cancel", to: "devise/registrations#cancel", as: :cancel_user_registration
get "/users/sign_up", to: "devise/registrations#new", as: :new_user_registration
get "/users/edit", to: "devise/registrations#edit", as: :edit_user_registration
patch "/users", to: "devise/registrations#update", as: :user_registration
put "/users", to: "devise/registrations#update"
delete "/users", to: "devise/registrations#destroy"
post "/users", to: "devise/registrations#create"
end
end

NoMethodError in Devise::Registrations#new

I keep getting this error when I try to sign up on my application, I am using devise for authentication;
NoMethodError in Devise::Registrations#new
undefined method `registration_path' for #<#<Class:0x007fe45c6c35e8>:0x007fe45d9ffd78>
Extracted source (around line #3):
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
When I run rake routes I get;
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
Sign up link code;
<%= link_to "Sign up", new_user_registration_path%>
UPDATE
Thanks to ParaPenguin the sign up field works now, but when I click submit I keep getting this problem
No route matches [POST] "/users/sign_up"
new_user_session_path GET /users/sign_in(.:format) devise/sessions#new
user_session_path POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session_path DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password_path POST /users/password(.:format) devise/passwords#create
new_user_password_path GET /users/password/new(.:format) devise/passwords#new
edit_user_password_path GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration_path GET /users/cancel(.:format) devise/registrations#cancel
user_registration_path POST /users(.:format) devise/registrations#create
new_user_registration_path GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration_path GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format)
Update 2-Gjaldon asked me to include my user model and routes
My user model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Routes.rb
Document::Application.routes.draw do
devise_for :users
root "pages#home"
get "about" => "pages#about"
get "prices" => "pages#prices"
get "faq" => "pages#faq", :as => :faq
get "terms" => "pages#terms"
get "view" => "pages#view"
get "policy" => "pages#policy"
get "contact" => "pages#contact"
get "works" => "pages#works"
Could you provide your routes for Devise in your routes.rb and the devise code for your User model?
It's either one of the following that might fix your problem:
Restart your Rails server. This way, Rails will see the new files and changes Devise has made to Rails.
Did you override the Devise::Registrations#new action? If so, you will need to replace your view code below:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
with:
<%= form_for(resource, :as => resource_name, :url => user_registration_path) do |f| %>
In your devise_registrations/edit.html.erb view, your form_for code would look like:
<%= form_for(resource, :as => resource_name, :url => edit_user_registration_path(resource_name, :method => :put) do |f| %>
Your rake routes actually provides you with the routes you need to submit to. Just keep in mind that the corresponding controller and action is displayed under the Controller#action column in the output of rake routes. The form in edit action should always submit to the update action and the form in new action should always submit to the create action if you stick to the Rails conventions. If you decide to have a form in another action for creating a record, then make sure to have the form submit to the create action.
Try changing registration_path(resource_name) from
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
to new_registration_path(resource_name). This could fix the error but I am not certain, it's possible. It seems that it is only for you as that file setup runs just fine for my devise.

Unable to over-write devise routes

I am using devise and I want to customize its urls:
users/sign_in --> account/login
users/sign_up --> account/register
users/edit --> account/profile
...
Now my routes.rb looks like this:
devise_scope :user do
get '/account/login' => 'devise/sessions#new'
post 'account/login' => 'devise/sessions#create', as: :user_session
delete 'account/logout' => 'devise/sessions#destroy', as: :destroy_user_session
post 'account/password' => 'devise/passwords#update', as: :user_password
get 'account/password/forgot' => 'devise/passwords#new', as: :new_user_password
get 'account/password/edit' => 'devise/passwords#edit', as: :edit_user_password
put 'account/password' => 'devise/passwords#update'
get 'account/cancel' => 'devise/registrations#cancel', as: :cancel_user_registration
post 'account' => 'devise/registrations#create', as: :user_registration
get 'account/register' => 'devise/registrations#new', as: :new_user_registration
get 'account' => 'devise/registrations#edit', as: :edit_user_registration
put 'account' => 'devise/registrations#edit'
delete 'account' => 'devise/registrations#destroy'
end
devise_for :users
I manage to over-write profile, forgot, register bug not login:
So when I click on the link "Sign up" link in the generic Devise Login form I am redirected to /register in the browser, but when I click the "Sign in" link I am still redirected to /users/sign_in rather than login.
I tried match vs. post + get for the routes but without luck. I know that if I generate the forms myself I can decide how the links look like, but I would prefer to user the generic devise forms and also I am curious why the other routes work.
Running rake routes produces this (with the top five rows from my routes):
new_user_session GET /account/login(.:format) devise/sessions#new
user_session POST /account/login(.:format) devise/sessions#create
destroy_user_session DELETE /account/logout(.:format) devise/sessions#destroy
user_password POST /account/password(.:format) devise/passwords#update
new_user_password GET /account/password/forgot(.:format) devise/passwords#new
edit_user_password GET /account/password/edit(.:format) devise/passwords#edit
account_password PUT /account/password(.:format) devise/passwords#update
cancel_user_registration GET /account/cancel(.:format) devise/registrations#cancel
user_registration POST /account(.:format) devise/registrations#create
new_user_registration GET /account/register(.:format) devise/registrations#new
edit_user_registration GET /account(.:format) devise/registrations#edit
account PUT /account(.:format) devise/registrations#edit
DELETE /account(.:format) devise/registrations#destroy
new_user_session GET /users/sign_in(.:format) devise/sessions#new
POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
POST /users/password(.:format) devise/passwords#create
GET /users/password/new(.:format) devise/passwords#new
GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
GET /users/cancel(.:format) devise/registrations#cancel
POST /users(.:format) devise/registrations#create
GET /users/sign_up(.:format) devise/registrations#new
GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root / posts#show
Update: I am now mimicking all of devise's routes (See updated routes.rb). But I am still redirected to /users/sign_in
You can try this, This is working
see more help devise wiki
devise_for :users, :path => '', :path_names => {:sign_in => 'login', :sign_out => 'logout'}
This should work. Also remove the /account and add path account to your routes file like I've done below.
devise_scope :user, path: "account" do
get "login", :to => "devise/sessions#new", :as => "login"
get "signup" => "users/registrations#new", :as => "register"
get "edit" => "edit_user_registration", :as => "edit"
end

Rails partial render and devise action

In my rails app i go for example to devise sign up action (http://*:3000/users/sign_up) and get error:
No route matches {:controller=>"devise/vehicle_types", :action=>"search_vehicle_type"}
I thing it's becouse i'm in devise namespace of routing... But how can i normally render sign up view? My layout part look's so:
= render :partial => 'vehicle_types/findtype'
and this partial:
.form
= form_tag :controller => 'vehicle_types', :action => 'search_vehicle_type' do
= select("post", "MFA_ID", Manufacturer.all.collect {|p| [ p.MFA_BRAND, p.MFA_ID ] }, {:prompt => 'Марка'}, :class => "login-input man-select")
= select_tag "models", options_for_select(['Модель', nil]), :class => "login-input mod-select", :prompt => 'Модель', :disabled => :true
= select_tag "fueltype", options_for_select([['Тип топлива', nil], ['Не важно', nil], ['Бензин', 53302], ['Дизель', 53205], ['Газ', 53241], ['Гибрид', 55554], ['Электродвигатель', 52433]]), :class => "login-input fuel-select"
= text_field_tag "year", nil, :placeholder => "Год выпуска", :class => "login-input"
.submit-area
.left
= submit_tag "Выбор", :class => "orange-button"
On other pages (non-devise) all is ok, but when i go to password recovery, or sign up i get erros. But why? And how to solve it?
Also part of routes:
Oleg::Application.routes.draw do
devise_for :users
match '/search_vehicle_type' => 'vehicle_types#search_vehicle_type'
root :to => 'pages#index'
end
Also i read about links here https://github.com/plataformatec/devise/issues/471, but how for partial to do?
and rake routes | grep devise
new_admin_session GET /admins/sign_in(.:format) devise/sessions#new
admin_session POST /admins/sign_in(.:format) devise/sessions#create
destroy_admin_session DELETE /admins/sign_out(.:format) devise/sessions#destroy
admin_password POST /admins/password(.:format) devise/passwords#create
new_admin_password GET /admins/password/new(.:format) devise/passwords#new
edit_admin_password GET /admins/password/edit(.:format) devise/passwords#edit
PUT /admins/password(.:format) devise/passwords#update
cancel_admin_registration GET /admins/cancel(.:format) devise/registrations#cancel
admin_registration POST /admins(.:format) devise/registrations#create
new_admin_registration GET /admins/sign_up(.:format) devise/registrations#new
edit_admin_registration GET /admins/edit(.:format) devise/registrations#edit
PUT /admins(.:format) devise/registrations#update
DELETE /admins(.:format) devise/registrations#destroy
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
While it may not be the best style, the easiest fix to this is to use an actual path in the form_tag:
.form
= form_tag "/search_vehicle_type" do
# Rest of the form
Another alternative would be to name the route in your routes.rb file:
match '/search_vehicle_type' => 'vehicle_types#search_vehicle_type', :as => :search_vehicle_type
Then use that named route in the form_tag:
.form
= form_tag search_vehicle_type_path do
# Rest of the form

Resources