【问题标题】:Show link if session user matches certain criteria如果会话用户符合某些条件,则显示链接
【发布时间】:2013-12-01 22:09:49
【问题描述】:

我正在尝试使我的应用程序中的特定链接仅对属性:department 等于“销售”的用户可见。

换句话说,我有一个模型Users,其中一个用户有passwordusernamedepartment。用户登录后,会话将保存:user_id

我想做的是当我的视图被渲染时,取决于登录用户的:department,要么显示,要么不显示特定链接。

这是我认为的代码,但我正在为如何获取会话信息并从中找到用户的部门而苦苦挣扎。

<% if Users.where(id: session[:user_id])[:department] == "Sales" %>
  <%= link_to 'New Request', new_request_path %>
  <% else nil %>
<% end %>

我知道在控制器或模型之外的任何地方进行查询都是不好的,所以如果您对如何更好地构建此逻辑有任何建议,我将不胜感激。

【问题讨论】:

    标签: ruby-on-rails activerecord session-variables actionview


    【解决方案1】:

    我想你想要的是:

    <% user = User.find_by_id(session[:user_id]) %>
    <% if user.present? && user[:department] == "Sales" %>
      <%= link_to 'New Request', new_request_path %>
    <% end %>
    

    就我个人而言,我会将其放入一个辅助方法中进行清理:

    在 app/helpers/users_helper.rb 中:

    def user_in_sales?
      user = User.find_by_id(session[:user_id])
    
      user.present? && user[:department] == "Sales"
    end
    

    那么你的看法:

    <% if user_in_sales? %>
      <%= link_to 'New Request', new_request_path %>
    <% end %>
    

    就个人而言,我强烈考虑使用cancan 之类的东西来处理这种情况。我想您可能会发现您可以在应用程序的其他地方使用 cancan 作为有效的授权工具,尤其是当您在其他地方执行类似的逻辑时。

    【讨论】:

      【解决方案2】:

      首先,您使用的是面向对象的语言。这将帮助您摆脱对实现细节的束缚(例如部门 ==“销售”),而是考虑您试图表达的意图或含义并编写代码来满足这一点。例如:

      if current_user.works_in?(:jewelry)
        link_to 'Request Receipt', new_request_path
      end
      

      您的模型应该公开一个公共接口,允许您代码中的其他对象(例如您的控制器)获取他们需要的信息(即用户是否与部门有关联),而无需了解或关心底层数据存储架构。

      class User
        def works_in?(department_name)
          departments.pluck(:name).include?(department_name.to_s)
        end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-30
        • 2020-05-03
        • 1970-01-01
        • 2020-03-24
        • 1970-01-01
        • 2020-10-27
        • 2019-05-12
        相关资源
        最近更新 更多