I'm trying to override the create method from the Registrations Controller in Devise to include Recaptcha verification (as seen here and here):
class RegistrationsController < Devise::RegistrationsController
def create
if verify_recaptcha
super
else
build_resource
clean_up_passwords(resource)
flash[:alert] = "Bad words."
render_with_scope :new
end
end
end
Also changed my routes.rb accordingly:
map.devise_for :users, :controllers => {:registrations => "registrations"}, :path_names => {
:sign_up => 'signup',
:sign_in => 'login',
:sign_out => 'logout'
}
When trying to visit the new registration page (with new path name: http://localhost:3000/users/signup) this errors shows up:
LoadError in RegistrationsController#new
Expected /home/benoror/project/app/controllers/registrations_controller.rb to define RegistrationsController
FULL ERROR TRACE
Any help appreciated.
BTW, I'm using Devise 1.0.11 and Rails 2.3.10, thanks!
Is your controller in a Users module? If so, you will need class Users::RegistrationsController and
{:registrations => "users/registrations"}
Edit: According to José Valim, custom controllers don't work prior to Devise 1.1. No reason to be developing on < Rails 3 imho. Sorry I missed that in the original post.
Related
I have Rails 5 with Devise with Ajax login/registration and I want to remove GET requests for these two actions. The default sign_in/sign_up routes are changed. This is my routes.rb:
devise_for :users, :path => '', :path_names => { :sign_in => "login",
:sign_out => "logout", :sign_up => "registration" },
:controllers => {:sessions => 'sessions',
:registrations => 'registrations'
In sessions_controller.rb and registrations_controller.rb you can check the request type and return 404 if it's a GET request:
If you haven't monkey-patched your devise controller already, create the directory app/controllers/devise and add the file registrations_controller.rb to it:
class Devise::RegistrationsController < DeviseController
prepend_before_action: :check_get_request # you can limit it to certain actions with only: [:new, etc.]
private
def check_get_request
if request.get?
# respond with 404 or 422, or whatever
else
super
end
end
end
Same goes for sessions_controller. You might break something by disabling all GET requests, but you can target specific actions if need be: For reference: https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb
and: https://github.com/plataformatec/devise/blob/master/app/controllers/devise/sessions_controller.rb
Because I am using custom registration_controller and sessions_controller I just override the methods which show registration/login pages. Both methods are show. I add to both custom controllers this method:
def new
raise ActionController::RoutingError.new('Not Found')
end
which returns 404, if someone navigates to registration or login URL, but POST request works fine.
I have a problem with the devise gem, I have this controller.
class AdminController < ApplicationController
before_action :authenticate_user!
def index
end
def per
end
def po
end
end
When redirect to sign_in form , shows nothing
sign_in form
These are my routes:
match 'po' => 'admin#po', :via => :get
match 'per' => 'admin#per', :via => :get
match 'admin' => 'admin#index', :via => :get
match 'admin/index' => 'admin#index', :via => :get
match 'admin/per' => 'admin#per', :via => :get
match 'admin/po' => 'admin#po', :via => :get
devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }
root 'home#index'
I have three templates: application, admin and home
I overwrite the default route after log in
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
#before_action :authenticate_user!
def after_sign_in_path_for(resource)
#request.env['omniauth.origin'] || stored_location_for(resource) || admin_path
admin_path
end
end
My last gem installed:
gem 'bootstrap-sass'
You need to run the generator for Devise views which will copy the necessary files in your views folder:
Run:
rails g devise:views
There is more information on configuring the Devise views here
Your problem probably isn't with Devise, it looks systemic to me.
#config/routes.rb
namespace :admin do
root "application#index" #->
resources :model_controller, path: "", only: :index do #-> url.com/admin/...
collection do
get :po #-> you shouldn't really have this
get :per #-> you shouldn't really have this
end
end
end
devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }
This will give you the following:
#app/controllers/admin/application_controller.rb
class Admin::ApplicationController < ApplicationController
before_action :authenticate_user!
def index
# do something here
end
end
This gives you the ability to create a custom "dashboard" type page for your admin area, from which you'll be able to use controllers bound to models.
Your po and per actions really shouldn't be there - they are not part of the CRUD system
In regards to your Devise views, the other answers are correct in that you would be best to generate the Devise views in your app:
rails generate devise:views
This won't solve your problem (hence why I downvoted the other answers). It will simply put the views in your app. It will do nothing apart from put code in a different place.
You will need to debug the issue:
Check the action you're seeing at /users/sign_in
Check the code in the <body> tags (which you haven't shown)
If the HTML is there, there will be some other issue preventing it from loading
If there is no HTML, it will likely mean a problem with the core of Devise
What I would recommend you do is the following:
Generate your views
From your screenshot, show us the contents of the <body> tag
Screenshot your console log (this will show any errors)
Update your question with the above
This will give you a much clearer perspective on what the potential issue will be, and allow other community members to better define the solution.
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.
I want to render a different layout for signup and login pages.
There's s similar thread that deals with this problem, but it's not exactly the same.
I need to be able to render different layout just for signup and login pages only, not all the other actions in a controller.
under users/registrations_controller.rb
class Users::RegistrationsController < Devise::SessionsController
def new
render :layout => "auth"
end
end
My routes
MasterCard::Application.routes.draw do
devise_for :users, :controllers => { :registrations => "users/registrations" }, :path => "users", :path_names => { :sign_in => 'login', :sign_out => 'logout' }
devise_scope :user do
get "login", :to => "users/sessions#new"
# post "logout", :to => "users/sessions"
end
root :to => 'pages#home'
match '/about' => 'pages#about'
end
This is the error I get when i go to sign up page.
undefined methoderrors' for nil:NilClass`
First, do you mean to subclass Devise::RegistrationsController and not Devise::SessionsController?
Overriding devise controller actions seems a little hairy. You can avoid this in your case by just overriding the default layout that RegistrationsController uses:
class Users::RegistrationsController < Devise::RegistrationsController
layout "auth"
end
As for why you're getting that particular error:
You're redefining the new action in what I'm assuming should be Devise::RegistationsController which has the following definition:
def new
resource = build_resource({})
respond_with resource
end
It sets a resource which is then referenced in the devise helper method devise_error_messages!:
def devise_error_messages!
return "" if resource.errors.empty?
...
end
which is used in the default devise "sign_up" template, users/registrations/new.html.erb:
...
<%= form_for(resource, :as => resource_name, ...) do |f| %>
<%= devise_error_messages! %>
...
You see that error because you didn't define resource.
I know how to override default controllers and it is working, but now I need to add new action into Registrations controller.
I need to update user fields. I need to add First and Last name in this form, but I don't want to use standard edit page, because it will be separate page.
So I need other page. I have paypal..html.erb in my registrations folder, but I can't render it from action in regustrations controller.
Paypal action:
class RegistrationsController < Devise::RegistrationsController
def paypal
end
...
end
routes.rb:
devise_for :users, :controllers => {:registrations => 'registrations', :sessions => 'sessions'} do
match 'paypal' => 'registrations#paypal'
end
but somehow it render new registration file. Here is error:
NoMethodError in Registrations#paypal
Showing C:/1508/app/views/devise/registrations/new.html.erb where line #22 raised:
How I can use update form to do this and what I'm doing wrong ?
I added this to my routes to make it work
devise_scope :user do
get 'paypal(/:id)', :action => 'paypal', :controller => 'user/registrations', :as => 'paypal'
end
Your question seems a little unclear, however Why not explicitly render the view?
def paypal
render 'devise/registrations/paypal'
end
If you have multiple type of users it may be better to separate out the paths and routing.
https://github.com/plataformatec/devise/wiki/How-To%3a-Customize-routes-to-user-registration-pages