Devise's registration_path, how it's generated? - ruby-on-rails

Default Devise user signup form looks like this:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
When I run rake routes I don't see any registration prefix, there is user_registration, new_user_registration etc. but not just registration, so how does it work? Where can I find it's source code?

The registration_path route is generated in
Devise::Controllers::UrlHelpers.
As you can see in the code below it just calls your regular routes.
def self.generate_helpers!(routes=nil)
routes ||= begin
mappings = Devise.mappings.values.map(&:used_helpers).flatten.uniq
Devise::URL_HELPERS.slice(*mappings)
end
routes.each do |module_name, actions|
[:path, :url].each do |path_or_url|
actions.each do |action|
action = action ? "#{action}_" : ""
method = "#{action}#{module_name}_#{path_or_url}"
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
def #{method}(resource_or_scope, *args)
scope = Devise::Mapping.find_scope!(resource_or_scope)
_devise_route_context.send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
end
URL_HELPERS
end
end
end
end
generate_helpers!(Devise::URL_HELPERS)
With Devise::URL_HELPERS being:
{:session=>[nil, :new, :destroy], :omniauth_callback=>[], :password=>[nil, :new, :edit], :registration=>[nil, :new, :edit, :cancel], :confirmation=>[nil, :new], :unlock=>[nil, :new]}

Put the following in your routes.rb
devise_for :users, :controllers => {:sessions => 'devise/sessions', :registrations => 'devise/registrations',
:passwords => 'devise/passwords'}, :skip => [:sessions] do
get '/login' => 'devise/sessions#new', :as => :new_user_session
post '/login' => 'devise/sessions#create', :as => :user_session
get '/logout' => 'devise/sessions#destroy', :as => :destroy_user_session
end
And then run rake routes. You can find the devise controller at: List of Devise Controllers

Related

I keep getting, "NoMethodError (undefined method `moments' for nil:NilClass):"

I'm just start to learn ruby and I'm writing a simple API, but I've got an error NoMethodError (undefined method moments' for nil:NilClass): app/controllers/api/v1/moments_controller.rb:8:inindex' Here is a code:
Rails.application.routes.draw do
resources :posts
devise_for :users
namespace :api do
namespace :v1 do
devise_scope :user do
post 'registrations' => 'registrations#create', :as => 'register'
post 'sessions' => 'sessions#create', :as => 'login'
delete 'sessions' => 'sessions#destroy', :as => 'logout'
end
get 'moments' => 'moments#index', :as => 'moments'
post 'moments' => 'moments#create'
end
end
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
end`
here code : moments_controller.rb
class Api::V1::MomentsController < ApplicationController
skip_before_filter :verify_authenticity_token,
:if => Proc.new { |c| c.request.format == 'application/json' }
before_filter :authenticate_user!
def index
#moments = current_user.moments
end
def create
#moment = current_user.moments.build(params[:moment])
if #moment.save
#moment
else
render :status => :unprocessable_entity,
:json => { :success => false,
:info => #moment.errors,
:data => {} }
end
end
#private
# def moment_params
# params.require(:moment).permit(:title, :completed)
# end
end
Can anyone see what is wrong with my code?

Error trying to logout: Couldn't find User with 'id'=sign_out

I'm getting this error when I try to logout an user. I checked many posts of this same error but no one solved my error, I hope you can help me.
The error is as follows:
ActiveRecord::RecordNotFound in UsersController#destroy
Couldn't find User with 'id'=sign_out
The following is my code:
users_controller.rb
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to unauthenticated_root_path }
format.json { head :no_content }
end
end
private
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
view/users/index.html.erb
<li>
<%= link_to "Logout", destroy_user_session_path, :method => :delete %>
</li>
routes.rb
Rails.application.routes.draw do
get 'admin/index'
resources :contacts
resources :afections
resources :injuries
resources :allergies
resources :trainers
resources :idusuarios
resources :diseases
resources :weights
resources :diets
resources :exercices
resources :profiles
resources :users
devise_for :users
get '/users/sign_out' => 'devise/sessions#destroy'
devise_scope :user do
authenticated :user do
root 'pagina#index', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
end
move get '/users/sign_out' => 'devise/sessions#destroy' above resources :users in your routes. Routes are given priority in terms of their order in the routes file.
When you use resources :users in your routes, you have this routes:
/users
/users/:id
/users/:id/edit
and ...
So when /users/sign_out is called, , thinks the sign_out is an ID.
so change /users/sign_out to /user/sign_out for example.
BUT
if you want customize your session paths, you can do this:
customize your session paths:
as :user do
get 'user/signin' => 'devise/sessions#new', :as => :new_user_session
post 'user/signin' => 'devise/sessions#create', :as => :user_session
delete 'user/signout' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:delete, :get]
end
and skip session in devise:
devise_for :users, :skip => [:sessions]
if you want user registration, you must skip it in devise and then can use user scaffold:
as :user do
get 'user/signin' => 'devise/sessions#new', :as => :new_user_session
post 'user/signin' => 'devise/sessions#create', :as => :user_session
delete 'user/signout' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:delete, :get]
end
scope "admin" do
resources :users
devise_for :users, :skip => [:sessions, :registrations]
end

Class level method "undefined"

With the code below:
class TestController < ApplicationController
wrap_parameters :test, format: [:json, :xml], include: self.test_method
def self.test_method
[ :one, :two, :three ]
end
end
I get a RoutingError:
ActionController::RoutingError (undefined method 'test_method' for TestController:Class)
I tried a number of different derivations of this, but nothing is working.
EDIT: routes.rb -- was routing to api.servername/create during error:
TestApp::Application.routes.draw do
resources :subscriptions
# API subdomain
constraints subdomain: 'api' do
get '/' => 'test#index'
post '/create', to: 'test#create'
get '/status', to: 'test#show'
end
# root route
root to: 'pages#index'
# User routes
devise_scope :user do
get 'login' => 'devise/sessions#new', :as => :new_user_session
post 'login' => 'devise/sessions#create', :as => :user_session
delete 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
get 'register' => 'devise/registrations#new', :as => :new_user_registration
get 'profile' => 'devise/registrations#edit', :as => :edit_user_registration
get 'users' => 'users/registrations#index'
end
devise_for :users, :skip => [:sessions], controllers: { registrations: 'users/registrations' }
end

Ruby on Rails: not authorized to access sign up page?

I have devise and CanCan set up, but I'm trying to get into sign up page in my rails application, but its redirecting me to home page saying that I'm not authorized to access this page.
I have a custom registration controller:
class Devise::RegistrationsController < DeviseController
before_filter :check_permissions, :only => [:new, :create, :cancel]
skip_before_filter :require_no_authentication
def check_permissions
authorize! :create, resource
end
def edit
#user = User.find(current_user.id)
#profile = Profile.new
end
def update
# required for settings form to submit when password is left blank
if params[:user][:password].blank? && params[:user][:password_confirmation].blank?
params[:user].delete(:password)
params[:user].delete(:password_confirmation)
end
#user = User.find(current_user.id)
if #user.update_attributes(params[:user])
set_flash_message :notice, :updated
# Sign in the user bypassing validation in case his password changed
sign_in #user, :bypass => true
redirect_to after_update_path_for(#user)
else
render "edit"
end
end
protected
def after_update_path_for(resource)
user_path(resource)
end
private
end
It has something to do with before_filter :check_permissions,... because when I delete this line, I get an error saying
undefined method `user_registration_path'
from my registration form in my `devise/registrations#new:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
How do I fix my registration form?
Also, this is my routes:
devise_for :user, :controllers => { :registrations => "registrations" }, :skip => [:registrations, :sessions] do
get 'signup' => 'devise/registrations#new', :as => :new_user_registration
end
Okay from what it looks like you've done is used CanCans authorize! method to handle the authorization in a controller action which will raise the cancan exception error. Can you not try and do
check_authorization :unless => :devise_controller?
I back this up with a change made a cancan commit seen here adding :if and :unless options to check_authorization - closes #284. Comments can be seen in the following issue: GitHub issue 284. Where Ryan states:
It would be nice if the check_authorization method allowed a block to dynamically customize the behavior. If it returned true it would perform the authorization.
Correct me if I am wrong but is this not what you are trying to do. Hopefully this sheds some light.
Another thing with regards to your routes.rb where you have done:
devise_for :user, :controllers => { :registrations => "registrations" }, :skip => [:registrations, :sessions] do
get 'signup' => 'devise/registrations#new', :as => :new_user_registration
end
This all looks a bit mis-match to me. Do you have by any chance a devise folder containing all devise controllers in your controller directory. If so could you not try and make your devise route block look like the following:
devise_for :users, :controllers => {:sessions => 'devise/sessions', :registrations => 'devise/registrations', :passwords => 'devise/passwords'}, :skip => [:sessions] do
get '/login' => 'devise/sessions#new', :as => :new_user_session
get '/register' => 'devise/registrations#new', :as => :registrations
post '/login' => 'devise/sessions#create', :as => :user_session
get '/logout' => 'devise/sessions#destroy', :as => :destroy_user_session
end
update
From the link GitHub - CheckAuthorizationI pasted in my comment I believe you can the method check_authorization as the example shows you can do:
class ApplicationController < ActionController::Base
check_authorization
end
The controller then shows that you can:
Supply the name of a controller method to be called. The authorization check only takes place if this returns false.
check_authorization :unless => :devise_controller?

Devise routing error: "Unknown action -- The action 'create' could not be found for UsersController"

My devise set up was working fine before, but now, for some reason, whenever I try to sign up a new user, it tries to call users#create instead of registrations#create. I think it must be a problem with my routes.rb file. I recently added a new resource, "preferences", to my application, so the routing might be wonky:
Indexer2::Application.routes.draw do
resources :preferences
get "home/index"
resources :posts
resources :users
devise_for :users, :controllers => {:registrations => 'registrations', :invitations => 'invitations'}, :except => [:show] do
get "/signup" => "devise/registrations#new", :as => 'user_signup'
get '/logout' => 'devise/sessions#destroy', :as => 'user_logout'
get '/login' => "devise/sessions#new", :as => 'user_login'
end
match '/welcome' => 'pages#welcome'
resources :preferences, :except => [:destory, :edit, :create, :new, :index, :show] do
collection do
post "make_feed_preference"
post "change_preference"
end
end
root :to => "home#index"
end
Your UsersController should have create method.
If you don't want to write your own registration logic just do inheritance from Devise::RegistrationsController < DeviseController:
controller UsersController < Devise::RegistrationsController
#....
end
This will include default Devise methods.

Resources