如果会话用户符合特定条件,则显示链接

时间:2013-11-18 16:51:27

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

我正在尝试在我的应用程序中创建一个特定链接,只有属性:department等于“Sales”的用户才能看到。

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

我想要做的是呈现我的视图,具体取决于登录用户的:department,显示或不显示特定链接。

以下是我在视图中得到的代码,但我正在努力解决如何获取会话信息并从中找到用户部门的问题。

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

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

2 个答案:

答案 0 :(得分: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作为你应用中其他地方的有效授权工具,特别是如果你在其他地方做这样的逻辑。

答案 1 :(得分:1)

首先,您使用的是面向对象的语言。它可以帮助您戒掉实施细节(例如,部门==“销售”),而是考虑您尝试表达的意图或意义以及为满足这一要求而编码。例如:

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