Hans
Hans

Reputation: 133

Rails error resource_name - devise help routing and rendering

I am trying to render the login view for the Devise gem but I get an error, below is the code I currently have:

This is my views/users/shared/_links.html.erb:

<%- if controller_name != 'sessions' %>
  <%= link_to "Sign in", new_session_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
  <%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
  <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
  <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
  <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.omniauthable? %>
  <%- resource_class.omniauth_providers.each do |provider| %>
    <%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
  <% end -%>
<% end -%>

And my config/routes.rb:

Densidste::Application.routes.draw do
  match 'user/edit' => 'users#edit', :as => :edit_current_user

  match 'signup' => 'devise/users#new', :as => :signup

  match 'logout' => 'devise/sessions#destroy', :as => :logout

  devise_for :users do
    get "login", :to => "devise/sessions#new"
  end

  resources :sessions

  resources :users

  devise_for :users

  resources :aktivs

  resources :taggingposts

  resources :tags

  resources :kommentares

  resources :posts

  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  root :to => "public#index"
end

And in my application layout:

<%= render("users/shared/links") %>

I get the following error in the _links.html.erb partial:

NameError in Public#index

Showing C:/Rails/Densidste/app/views/users/shared/_links.erb where line #2 raised:

undefined local variable or method `resource_name' for #<#<Class:0x5db76c0>:0x5db6538>

Extracted source (around line #2):

1: <%- if controller_name != 'sessions' %>
2:   <%= link_to "Sign in", new_session_path(resource_name) %><br />
3: <% end -%>
4: 
5: <%- if devise_mapping.registerable? && controller_name != 'registrations' %>

Trace of template inclusion: app/views/public/index.html.erb

Rails.root: C:/Rails/Densidste

Finally, in my application controller I have the following:

before_filter :resource_name
  def resource_name
    if user_signed_in?
      current_user.name
    else
      :user
    end
  end
end

Any help would be much appreciated, thanks!

Upvotes: 9

Views: 14886

Answers (3)

Fazal Ur Rehman Fazal
Fazal Ur Rehman Fazal

Reputation: 129

you can resolve this error my replacing your app/views/devise/confirmation/new.html file with

https://github.com/heartcombo/devise/pull/3684/files

with the file app/views/devise/confirmation/new.html in above link you can find this file from above link and replace your file with it beacuse there are some changes made in recent version so visit above link and find app/views/devise/confirmation/new.html file from above link and replace it with your project file app/views/devise/confirmation/new.html file

Upvotes: 0

Michael Yagudaev
Michael Yagudaev

Reputation: 6129

The problem is that in your routes.rb file you are defining a resource called sessions, devise also has a resource with the same name.

The solution is simple, just remove the resources :sessions from the routes file and everything should work.

The reason this happens is because rails creates route helpers for all resources. So it creates a route helper called new_session_path(format). But devise also creates a helper method called new_session_path(resource_name). The devise version returns a path new_<resouce_name>_session_path. In other words, the helpers generated by the routes file override the ones in devise.

Note that this can also happen if you do something like:

devise_scope :user do 
  get 'login', :to => 'devise/sessions#new', :as => :new_session
  get 'logout', :to => 'devise/sessions#destroy', :as => :destroy_session
end

In that case, the solution is to replace new_session and destroy_session with login and logout respectively.

Upvotes: 0

andrewmitchell
andrewmitchell

Reputation: 1619

resource_name is defined in the Devise generated controllers. I don't think you can include those shared links in the application layout, I think they are intended for use on the devise forms (registration,sessions,passwords,confirmations,etc), which are rendered by devise controllers.

If you want to have little login/out snippets in every page, you might want to consider writing those links yourself. For instance, if your object that you're using devise for is user, you could write this:

<%= link_to "Sign in", new_session_path(:user) %><br />

the resource_name is just the Devise abstraction for the resource you're using. I expect that if you're making this link, you know which of your authenticated objects you want to login as, so you can specify it explicitly. You could aslo run rake routes | grep sessions and see what the name of the path is and use that directly. For example:

<%= link_to "Sign in", new_user_session_path %><br />

Upvotes: 21

Related Questions