3

I have a form on my layouts/application.html.erb that is posted below and and if i add the line <%= devise_error_messages! %> I get the error below.

How can i add the devise_error_messages without having the page break?

/app/views/layouts/application.html.erb

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
    <%= devise_error_messages! %>  <!-- this line causes issues -->
    <h3>Add new contact</h3>
    First Name<br />
    <%= f.text_field :username %><br />
    Last Name<br />
    <%= f.text_field :password %><br />
    <%= f.text_field :password_confirmation %><br />                                
    Email<br />
    <%= f.text_field :email %>
    <hr />
    <%= f.submit "Add Contact" %>

<% end %>

Error:

NoMethodError in My_devise/sessions#index

Showing /app/views/layouts/application.html.erb where line #59 raised:

undefined method `errors' for nil:NilClass

Extracted source (around line #59):

56:                             <a href="#" class="has-popupballoon button button-blue"><span class="add"></span>New Contact</a>
57:                             <div class="popupballoon top">
58:                             <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
59:   <%= devise_error_messages! %>
60:                                 <h3>Add new contact</h3>
61:                                 First Name<br />
62:                                 <%= f.text_field :username %><br />

This is the url i'm using http://localhost:3000/admin/home and here's my routes.rb

devise_for :users do 
    get '/users/sign_out' => 'devise/sessions#destroy' 
    get "/users/sign_in", :to => "my_devise/sessions#new"
    get 'admin/home', :to => 'my_devise/sessions#index'
    get 'users/sign_up', :to => 'my_devise/registrations#new'
  end 

  devise_for :users, :controllers => {:sessions => "my_devise/sessions", :registrations => "my_devise/registrations"}
  get "home/index"
  root :to => "home#index"

/app/controllers/my_devise/sessions_controller.rb

class MyDevise::SessionsController < Devise::SessionsController
    layout false

    before_filter :authenticate_user!

    def index
        render :layout => 'application'
    end

    def new
        super
    end

    def create
        super
    end

end

/app/controllers/my_devise/registrations_controller.rb

class MyDevise::RegistrationsController < Devise::RegistrationsController

    def index

    end

end

Rake routes:

users_sign_out GET    /users/sign_out(.:format)      {:controller=>"devise/sessions", :action=>"destroy"}
           users_sign_in GET    /users/sign_in(.:format)       {:controller=>"my_devise/sessions", :action=>"new"}
              admin_home GET    /admin/home(.:format)          {:controller=>"my_devise/sessions", :action=>"index"}
           users_sign_up GET    /users/sign_up(.:format)       {:controller=>"my_devise/registrations", :action=>"new"}
        new_user_session GET    /users/sign_in(.:format)       {:action=>"new", :controller=>"devise/sessions"}
            user_session POST   /users/sign_in(.:format)       {:action=>"create", :controller=>"devise/sessions"}
    destroy_user_session DELETE /users/sign_out(.:format)      {:action=>"destroy", :controller=>"devise/sessions"}
           user_password POST   /users/password(.:format)      {:action=>"create", :controller=>"devise/passwords"}
       new_user_password GET    /users/password/new(.:format)  {:action=>"new", :controller=>"devise/passwords"}
      edit_user_password GET    /users/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
                         PUT    /users/password(.:format)      {:action=>"update", :controller=>"devise/passwords"}
cancel_user_registration GET    /users/cancel(.:format)        {:action=>"cancel", :controller=>"devise/registrations"}
       user_registration POST   /users(.:format)               {:action=>"create", :controller=>"devise/registrations"}
   new_user_registration GET    /users/sign_up(.:format)       {:action=>"new", :controller=>"devise/registrations"}
  edit_user_registration GET    /users/edit(.:format)          {:action=>"edit", :controller=>"devise/registrations"}
                         PUT    /users(.:format)               {:action=>"update", :controller=>"devise/registrations"}
                         DELETE /users(.:format)               {:action=>"destroy", :controller=>"devise/registrations"}
        new_user_session GET    /users/sign_in(.:format)       {:action=>"new", :controller=>"my_devise/sessions"}
                         POST   /users/sign_in(.:format)       {:action=>"create", :controller=>"my_devise/sessions"}
    destroy_user_session DELETE /users/sign_out(.:format)      {:action=>"destroy", :controller=>"my_devise/sessions"}
                         POST   /users/password(.:format)      {:action=>"create", :controller=>"devise/passwords"}
                         GET    /users/password/new(.:format)  {:action=>"new", :controller=>"devise/passwords"}
                         GET    /users/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
                         PUT    /users/password(.:format)      {:action=>"update", :controller=>"devise/passwords"}
                         GET    /users/cancel(.:format)        {:action=>"cancel", :controller=>"my_devise/registrations"}
                         POST   /users(.:format)               {:action=>"create", :controller=>"my_devise/registrations"}
                         GET    /users/sign_up(.:format)       {:action=>"new", :controller=>"my_devise/registrations"}
                         GET    /users/edit(.:format)          {:action=>"edit", :controller=>"my_devise/registrations"}
                         PUT    /users(.:format)               {:action=>"update", :controller=>"my_devise/registrations"}
                         DELETE /users(.:format)               {:action=>"destroy", :controller=>"my_devise/registrations"}
              home_index GET    /home/index(.:format)          {:controller=>"home", :action=>"index"}
                    root        /                              {:controller=>"home", :action=>"index"}
                    root        /                              {:controller=>"home", :action=>"index"}
Catfish
  • 18,876
  • 54
  • 209
  • 353
  • Does the form successfully submit when you take out the devise_error_messages ? – Kyle C Jun 27 '12 at 05:05
  • No it just redirects to `localhost:3000` whether you fill in all the fields or no fields and even if you fill out all the fields it does not add a record to the db. – Catfish Jun 27 '12 at 05:10
  • I've updated my routes.rb file and i've added my registrations_controller.rb file and the form works when i'm on `http://localhost:3000/users/sign_up`, but not when i'm on `http://localhost:3000/admin/home`. – Catfish Jun 27 '12 at 05:26
  • Thank you just about to ask for that, the routing is very messed up. I am confused, do you mean to have both a MyDevise and Devise controllers? – Kyle C Jun 27 '12 at 05:38
  • MyDevise controllers are supposed to override/extend the Devise controllers. It seems that i need these in order to get the form working from every page on my site. – Catfish Jun 27 '12 at 12:57
  • Your MyDevise controllers are not overriding the devise controllers. If you look at the your rake routes output, you have two full routes for registrations and sessions. In rails, the routes at the top take priority so they are being overridden. – Kyle C Jun 27 '12 at 16:29
  • Routes 2, 3, and 4 are all from my_devise so they are overriding the controller correct? – Catfish Jun 27 '12 at 17:28
  • Correct, but you are also overriding your create action in your controller and your destroy action should not be a GET request it should be DELETE – Kyle C Jun 27 '12 at 18:02
  • If you're referring to line 1 in my rake routes thats straight from the devise gem. – Catfish Jun 27 '12 at 19:19
  • the get '/users/sign_out' => 'devise/sessions#destroy' , shouldnt be a "get" request. – Kyle C Jun 27 '12 at 20:56
  • oh i see now that i put that in my routes file. – Catfish Jun 27 '12 at 21:24

3 Answers3

2

I had what may be a similar problem.

It took me awhile to figure it out, but in my case it was due to this :

def current_user
  @current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user

in my application_controller.rb file.

I added this line from a tutorial. After I removed this, I received no more errors about "devise_error_messages". I don't quite understand why this would upset things, perhaps 'current_user' is defined elsewhere and it sets up (or leads to the setting up) of the error object.

j0k
  • 22,600
  • 28
  • 79
  • 90
William
  • 1,295
  • 1
  • 10
  • 19
0

Try changing your devise_for routing, checkout this documentation http://rdoc.info/github/plataformatec/devise#Configuring_routes

You can add your own prefix with the :path parameter

Here is a sample

devise_for :users, :path => "", :path_names => {
 :sign_in => 'signin',
 :sign_out => 'signout',
 :sign_up => 'signup'            
 },
:sign_out_via => [:delete],

 :controllers => {:sessions => 'my_devise/sessions', :registrations => 
  'my_devise/registrations'}
Kyle C
  • 4,077
  • 2
  • 31
  • 34
  • take off the before_filter and try – Kyle C Jun 27 '12 at 05:22
  • I've actually glared at that piece of the documentation and stil. can't figure it out. I'm very new to rails yet so things are still pretty cryptic to me. What would i put in the :path parameter and should there be something about localhost:3000/admin/home in your example? – Catfish Jun 27 '12 at 12:56
  • Above I left :path as an empty string. This would not append "/user" to all the routes so it would just be localhost:3000/signin and localhost:3000/signout . – Kyle C Jun 27 '12 at 16:39
  • I think the sample you've posted is incorrect because there is a a comma after :sign_out_via => [:delete] and if i remove it, i get the error expecting keyword_end. – Catfish Jun 27 '12 at 17:17
  • Do i need to put your entire sample in my `devise_for :users do ... end`? So it will have devise_for :users nested. – Catfish Jun 27 '12 at 19:17
  • Try erasing the existing devise routes and just plugin my sample. Are you following a tutorial or any examples to setup devise? – Kyle C Jun 27 '12 at 20:57
  • i tried that already. it gives me an error expecting keyword_end. I'm not following a tutorial. i've already tried got a little project working with devise, but now i'm trying another project where i want someone to be able to add users from every page via a form in the header(the form posted in my question) and it's giving me so much trouble. – Catfish Jun 27 '12 at 21:26
  • Here is a couple links to help you add users on every page, https://github.com/plataformatec/devise/wiki/How-To:-Display-a-custom-sign_in-form-anywhere-in-your-app and http://stackoverflow.com/questions/4081744/devise-form-within-a-different-controller ........... Is there anything you can see in the logs? – Kyle C Jun 27 '12 at 21:39
0

Revisiting a project I haven't had time to touch in a while, but the simple answer was just to create the User object in the application_controller.

I added this snippet to the application_controller:

before_filter :instantiateUser

def instantiateUser
    @user = User.new
end
Catfish
  • 18,876
  • 54
  • 209
  • 353