什么是devise_mapping变量,我该如何包含它?

时间:2010-12-27 19:00:42

标签: ruby-on-rails authentication devise

我正在尝试使用我的Rails应用程序中的Devise实现身份验证(Rails 2.3.8,Devise 1.0.7,在Windows Vista上运行的mongrel)。但我收到以下错误:

undefined local variable or method `devise_mapping' for #<ActionView::Base:0x6d63890>

这是我使用自动生成的部分_devise_links.html。

<%- if controller_name != 'sessions' %>
  <%= link_to t('devise.sessions.link'), new_session_path(resource_name) %><br />
<% end -%>

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

<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
  <%= link_to t('devise.passwords.link'), new_password_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
  <%= link_to t('devise.confirmations.link'), new_confirmation_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.lockable? && controller_name != 'unlocks' %>
  <%= link_to t('devise.unlocks.link'), new_unlock_path(resource_name) %><br />
<% end -%>

有关如何解决此问题的任何想法?我假设devise_mapping变量没有包含在我的视图中,但我该怎么办呢?

4 个答案:

答案 0 :(得分:42)

您可以向ApplicationHelper添加辅助方法。确保使用正确的型号名称(在我的情况下,它是代表:user型号的User)。

def devise_mapping
  Devise.mappings[:user]
end

def resource_name
  devise_mapping.name
end

def resource_class
  devise_mapping.to
end

2014年1月28日更新

Devise的主分支显示devise_mapping现在存储在请求中:

# Attempt to find the mapped route for devise based on request path
def devise_mapping
  @devise_mapping ||= request.env["devise.mapping"]
end

resource_name的别名为scope_name。有关详细信息,请参阅devise_controller.rb

答案 1 :(得分:6)

我意识到这个问题有点陈旧,但我想我弄清楚为什么你不能只是渲染那个偏。您尝试呈现的部分内容是显示在sign_in / sign_up表单下方的链接的部分内容。

如果您想将这些链接添加到您的应用中,this page on the Devise Wiki会告诉您如何操作,并且它涉及创建您自己的部分。

编辑(2019-04-01):在此处复制Devise wiki页面中的信息以保持持久性。

如何:将sign_in,sign_out和sign_up链接添加到布局模板

首先添加sign_in / out链接,因此将显示相应的链接,具体取决于用户是否_already_已登录:
# views/devise/menu/_login_items.html.erb
<% if user_signed_in? %>
  <li>
  <%= link_to('Logout', destroy_user_session_path, method: :delete) %>        
  </li>
<% else %>
  <li>
  <%= link_to('Login', new_user_session_path)  %>  
  </li>
<% end %>
如果使用默认HTTP方法,则需要method: :delete部分。要改变它,你需要告诉Devise:
# config/initializers/devise.rb
  # The default HTTP method used to sign out a resource. Default is :delete.
  config.sign_out_via = :get
然后,您可以在所有sign_out链接上省略method: :delete。 接下来是sign_up链接。同样,如果用户已经登录,这些可以替换为其他有用的东西:
# views/devise/menu/_registration_items.html.erb
<% if user_signed_in? %>
  <li>
  <%= link_to('Edit registration', edit_user_registration_path) %>
  </li>
<% else %>
  <li>
  <%= link_to('Register', new_user_registration_path)  %>
  </li>
<% end %>
然后在layouts/application.html.erb中使用这些模板,如下所示:
# layouts/application.html.erb
<ul class="hmenu">
  <%= render 'devise/menu/registration_items' %>
  <%= render 'devise/menu/login_items' %>
</ul>
<%= yield %>
将一些菜单样式添加到CSS(这里是水平菜单):
ul.hmenu {
  list-style: none; 
  margin: 0 0 2em;
  padding: 0;
}

ul.hmenu li {
  display: inline;  
}

答案 2 :(得分:2)

您可以使用devise_mapping,而不是使用Devise.mappings[:user],因为相关用户类是用户。

答案 3 :(得分:-1)

您的routes.rb文件中是否有devise_for调用?

例如,如果您将其用于User类,则路由将为:

devise_for:users

有关详细信息,请参阅https://github.com/plataformatec/devise