NoMethodError in Devise::Registrations#new - ruby-on-rails

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.

Related

Getting error Couldn't find User with 'id'=id

I am learning ruby on rails by making a project web app,
whenever i go to <%= link_to 'My Profile', user_path(:id) %> error Couldn't find User with 'id'=id" is shown...and url is "http://localhost:3000/users/id
If i convert above link to <%= link_to 'My Profile', user_path %>, it works but now all other pages except user's show page give error No route matches {:action=>"show", :controller=>"users"} missing required keys: [:id]....I cant seem to find any solution anywhere...
Here are my configs:
rake routes Prefix Verb URI Pattern Controller#Action
root GET / static#landing
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
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
user GET /users/:id(.:format) users#show
_header.html.erb
<%= link_to 'My Profile', user_path %>
users_controller.rb
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
end
routes.rb
Rails.application.routes.draw do
root 'static#landing'
devise_for :users
resources :users, :only => [:show]
You need to pass the id of a user to user_path, not the symbol :id - so something like
<%= link_to 'My Profile', user_path(#current_user.id) %>
if the user you want to link to is in an instance variable - or since you are using Devise and it provides the current_user helper you might be wanting
<%= link_to 'My Profile', user_path(current_user.id) %>
I think the first thing wrong is this:
<%= link_to 'My Profile', user_path(:id) %>
You are using a symbol, not a variable
<%= link_to 'My Profile', user_path(#id) %>
Would have an actual variable, assuming you have set #id in your controller.
Normally however you would not set the id for a user in a path - it's a recipe for someone to just change the number manually and view someone elses.
Lets assume you set a session variable called :user_id, then you should do something adding a collection route - so no id is sent.
resources :users do
get :show_profile, on: :collection
end
This gets you a path to your show_profile action, called with
link_to 'My Profile', show_profile_user_path
Then in your controller do your user look up from the session - so something like:
#user = User.find_by id: session[:user_id]
I don't know how devises does things, but please don't trust a user to not fiddle with your parameters!

undefined local variable or method with form_tag

I'm trying to create a simple search form in my Rails application. I get an error with the url path of the form:
<%= form_tag(med_search, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search", class: "form-control" %>
<%= button_to "Search", class: "btn btn-default" %>
<% end %>
The first line above causes error undefined local variable or methodmed_search' for #<#:0x007fab2b5afa90>`
The problem is most likely with my routes setup. I created a new controller action called search so I edited my routes.db to look like this:
resources :meds do
collection do
get 'search' => 'meds#search'
end
end
devise_for :users
#get 'meds/index'
root to: "meds#index"
resources :meds, :path => ''
end
When I do rake routes, I am seeing the path med search so I know the url is valid:
Prefix Verb URI Pattern Controller#Action
med_search GET /meds/:med_id/search(.:format) meds#search
meds GET /meds(.:format) meds#index
POST /meds(.:format) meds#create
new_med GET /meds/new(.:format) meds#new
edit_med GET /meds/:id/edit(.:format) meds#edit
med GET /meds/:id(.:format) meds#show
PATCH /meds/:id(.:format) meds#update
PUT /meds/:id(.:format) meds#update
DELETE /meds/:id(.:format) meds#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
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
root GET / meds#index
GET / meds#index
POST / meds#create
GET /new(.:format) meds#new
GET /:id/edit(.:format) meds#edit
GET /:id(.:format) meds#show
PATCH /:id(.:format) meds#update
PUT /:id(.:format) meds#update
DELETE /:id(.:format) meds#destroy
What should I change in the routes to fix this?
Thanks!
EDIT: changed url to med_search_path, get new error: No route matches {:action=>"search", :controller=>"meds"} missing required keys: [:med_id]. Looks like it's related to the route /meds/:med_id/search(.:format)
1) you need to change your form_tag like this
<%= form_tag(search_meds_path, :method => "get", id: "search-form") do %>
2) You need to change your route from member to collection like this
resources :meds do
collection do
get 'search' => 'meds#search'
end
end
3) Not sure why you need to add resources :meds, :path => '' at the bottom again. Incase you dont need it, it is better to remove.
It looks like you're trying to code up a search but because you put it in the resources block Rails is assuming you're talking about a specific med.
Remove the route from the resources block and change it to get 'meds/search' => 'meds#search'. That will allow you to use it as just a regular endpoint without Rails complaining that you need an ID.

Devise Update method does not have ID in route

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

Rails add new view to devise

I have generated views with this command after I installed devise
rails generate devise:views
and I override registration controller by
class RegistrationsController < Devise::RegistrationsController
def sign_up2
end
end
And updated routes.rb with
devise_for :users, :controllers => { :registrations => "registrations" }
I expected to see a new route/view of
/users/sign_up2
but I don't see it
And here routes for devise
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) registrations#cancel
user_registration POST /users(.:format) registrations#create
new_user_registration GET /users/sign_up(.:format) registrations#new
edit_user_registration GET /users/edit(.:format) registrations#edit
PATCH /users(.:format) registrations#update
PUT /users(.:format) registrations#update
DELETE /users(.:format) registrations#destroy
But I would like a new view and route
Update:
issue when I load view
First argument in form cannot contain nil or be empty
in this line
<%= form_for(resource, :as => resource_name,:html => { :class => "form-horizontal col-sm-12",:role=>"form"}, :url => user_registration_path(resource_name)) do |f| %>
Invoke a devise_scope block and declare your custom route within:
devise_for :users, :controllers => { :registrations => "registrations" }
devise_scope :user do
get "users/sign_up2"=> "users/registrations#sign_up2", :as => "sign_up2_registration"
end
The section on Configuring routes in the documentation provides the following explanation of devise_scope:
If you have the need for more deep customization, for instance to also allow "/sign_in" besides "/users/sign_in", all you need to do is to create your routes normally and wrap them in a devise_scope block in the router
Previously, Devise allowed custom routes to be passed as a block to devise_for, but this behavior has been deprecated.
UPDATE:
To address the First argument in form cannot contain nil or be empty error, you need to ensure that your custom sign_up2 action is properly setting the resource variable. Assuming you want to mimic the registrations/new action, you can do something akin to the following:
def sign_up2
build_resource({})
respond_with self.resource
end
This ensures that the resource variable in your view is not nil and will not throw the exception you're currently witnessing.
Alternatively, depending on the behavior you're trying to evince, you can set your own instance variable in the custom controller action, then pass it as the resource to your form_for tag:
# app/controllers/users/registrations_controller.rb
def sign_up_2
#new_registrant = Registrant.new
end
# app/views/users/sign_up2.html.erb
<%= form_for(#new_registrant, :as => resource_name,:html => { :class => "form-horizontal col-sm-12",:role=>"form"}, :url => user_registration_path(resource_name)) do |f| %>
However, if you follow this approach, you should consider why you need to roll this into Devise. Devise, by default, assigns the resource variable via the build_resource function. If you're going to override/bypass this function, you should consider abstracting this entire functionality out of Devise since you're totally circumventing its default behavior.

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