【问题标题】:Get UserID for Current User using Devise/Rails使用 Devise/Rails 获取当前用户的 UserID
【发布时间】:2023-03-29 11:41:01
【问题描述】:

所以我,一个 Rails 新手,目前正试图从当前的 Devise 会话中获取用户 ID,但我遇到了一些麻烦。

我的控制器中现在有这个:

def index
  @currentUser = current_user.id
end

我想做一个简单的 if 语句来显示/隐藏表单中的字段。

<% if @currentUser === @product.user_id %>
          <%= link_to "Back", products_path %>
          <%= link_to "Edit", edit_product_path(@product) %>
          <%= link_to "Delete", product_path(@product), method: :delete, data: { confirm: "Are you sure?"} %>
      <% else %>
          <span></span>
<% end %>

我感觉我在定义 currentUser 变量时的语法很糟糕,但我不知道如何解决这个问题。 Stack上有一些类似的问题,但没有一个真正适用于我或帮助我。

提前致谢!

【问题讨论】:

    标签: ruby-on-rails ruby devise


    【解决方案1】:

    我发现这里有一些问题

    def index
      @currentUser = current_user.id
    end
    

    除了@HolyMoly 已经注释的内容,你应该使用下划线而不是驼峰,如果这里current_user 是nil,.id 会失败,导致异常。

    其次,您通过比较 id 的值来检查“能力”,我会更改您的代码来执行此操作

    <% if allow_product_delete?(@product) %>
    

    在助手中

    def allow_product_delete?(product)
      return false unless current_user
      @product.user_id == current_user.id
    end
    

    如果您使用 devise current_user 存在于控制器和视图中,则无需将其定义为实例变量,它已经定义为所有操作的控制器方法(默认情况下)。所以通过在你的视图中调用current_user你就完成了。

    如果用户未登录,current_user 将为零,您始终必须为此做好准备并加以防范。

    最后,我会研究能力宝石(cancan 或 cancancan),它们提供了一个非常好的 DSL 来处理您在这里尝试的内容。

    【讨论】:

      【解决方案2】:

      您是否已将其设置为实际能够使用 current_user ? 在您的代码中:

      @currentUser = current_user.id

      但是 current_user 是在哪里定义的?我没有使用过 Devise,但是对于会话,您可以使用辅助方法定义 current_user 的值(您也可以在 session_controller #create 方法中直接执行此操作),如下所示:

       def current_user
           @current_user ||= User.find_by(id: session[:user_id])
        end
      

      然后,您可以在整个应用中使用 current_user.idcurrent_user.name 或任何您需要的东西。

      因此,虽然会话不是设计,但我希望这会有所帮助。

      【讨论】:

        【解决方案3】:

        首先,ruby 像 undescored_rather_than camelCased 风格。

        其次,您需要两个等号而不是三个等号。 @currentUser == @product.user_id 应该可以工作

        第三,你不需要比较整数id,你可以比较模型,类似这样:

        <% if current_user == @product.user %>
          <%= link_to "Back", products_path %>
          <%= link_to "Edit", edit_product_path(@product) %>
          <%= link_to "Delete", product_path(@product), method: :delete, data: { confirm: "Are you sure?"} %>
        <% end %>
        

        请注意,我在current_user 方法中省略了@,因为current_user 是设计的助手,否则我删除了不必要的&lt;% else %&gt;(在我看来)

        【讨论】:

        • 感谢您的快速回复。我试过这个,但没有成功,所以我想看看到底是什么比较,并打印出&lt;%= current_user %&gt;,得到#&lt;User:0x00000006e5e2e0&gt;。这是否与您所说的比较模型而不是整数 id 有关?
        • @aishaq11 这是正常情况 - 这代表具有唯一 ID 的 Object 类。在同一渲染中尝试 &lt;%= current_user.id %&gt;&lt;%= product.user_id %&gt; 之类的东西。 id 值是否相同?
        【解决方案4】:

        您应该为此使用 current_user。您可以在项目中的任何地方执行此操作。无需定义变量@currentUser 等。

        你可以比较喜欢的模型

        if current_user == @product.user
        

        相当于

        if current_user.id == @product.user.id
        

        在某些情况下你可以使用

        if current_user.id == @product.user_id
        

        这可以防止额外的 sql 查询来加载用户模型

        如果您使用 Devise 进行授权并且您需要控制访问权限以执行您应该看到(可能使用)gem https://github.com/CanCanCommunity/cancancan

        https://github.com/airbnb/ruby 将帮助您保持同步;)

        【讨论】:

          【解决方案5】:

          比较 ID 并不是 Rails 的最佳做法。如果您之前已正确设置关联,则无需在 ID 之间进行比较。例如:

          User
          has_many :group_events
          
          GroupEvent
          belongs_to :user
          

          这种场景下,不用比较ID,直接用关联比较即可:

          Bad
          @group_event.user_id == current_user.id
          
          Good
          @group_event.user == current_user
          

          【讨论】:

            猜你喜欢
            • 2011-05-08
            • 2020-11-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-22
            • 1970-01-01
            • 2012-09-01
            相关资源
            最近更新 更多