Rails Devise:如何获取当前登录用户的对象?

64

我最近在一个 Rails 应用程序中安装了 Devise,我想知道是否有可能在其他模型或控制器中获取当前登录用户的实例?如果可以,那么我该如何做呢?

4个回答

120

Devise会即时生成方便方法,用于表示当前登录的用户。

然而,需要注意的是所生成的方法名包含您的用户模型的类名。例如,如果您的Devise模型名为'User',那么可以使用'current_user'来访问当前已登录的用户;如果您的Devise模型名为'Admin',那么可以使用'current_admin'来访问当前已登录的管理员用户。

还有一些其他的方法也遵循了类似的约定,例如 'user_signed_in?' 或者 'admin_signed_in?',这些方法非常好用。

这些方法在控制器和视图中都可以使用,因此您可能会在视图中使用以下代码:

<% if user_signed_in? %>
  <div>Signed in as... <%= current_user.email %></div>
<% end %>

如果你的应用程序中使用了两个或多个Devise模型(例如User和Admin),则可以使用'anybody_signed_in?'便捷方法来检查这些类型的用户是否已登录:

<% if anybody_signed_in? %>
  <h2>Special offers</h2>
  <p>All registered users will receive free monkeys!</p>
<% end %>

更新:

由于 Devise 版本 1.2.0 开始,'anybody_signed_in?' 已被废弃并被 'signed_in?' 取代。


1
Scott所说的一切都是正确的,但也有一个新的东西,Devise在这里称呼useradmin为“scopes”。如果您在文档中看到这个词,那就是它所指的。 - Peeja
1
但这些信息在请求对象的哪里? - mehulkar

17

Devise的辅助方法仅在控制器和视图层可用。它们不适用于模型层(请参见README中的控制器过滤器和助手部分)。

  • 是否可以从模型中获取当前登录的用户?

使用Devise默认提供的帮助方法是不可能的。但是,有许多替代方法可供您使用,以提供current_user到模型中。最简单的方式已经由Alex Bartlow建议过了,就是通过一个方法将current_user传递给您的模型。

  • 是否可以从控制器中获取当前登录的用户?

是的,这是可能的。使用current_<modelname>,其中<modelname>是具有Devise身份验证功能的模型的名称(即通过rails g devise <modelname>)。例如,如果您的模型是User,则使用current_user。如果您的模型是Elmo,则使用current_elmo


1

simple method is:

if @suit.user == current_user

例子:
= link_to "Back", root_path, class: "btn btn-default"

  -if @suit.user == current_user

    = link_to "Edit", edit_suit_path, class: "btn btn-default"

    = link_to "Delete", suit_path, method: :delete, data: {confirm: "Are you sure?" }, class: "btn btn-default"

1
将其作为参数传递给方法调用 :).
一个想法是使用Thread.current[:current_user] = @current_user作为before_filter - 但如果您使用像Thin + EM_Mysql2 + Rack::FiberPool这样的部署堆栈,则需要将其设置为Fiber.current[:current_user]
这些解决方案实际上只是掩盖了缺乏良好设计逻辑的问题。

个人而言,我认为将上下文值粘贴到线程对象上是一种“异味”。你在最后一行已经承认了这一点,所以值得赞扬,但我想强调的是... - user483040

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接