我正在尝试在我的应用程序中创建一个特定链接,只有属性:department
等于“Sales”的用户才能看到。
换句话说,我有一个模型用户,其中用户有password
,username
和department
。一旦用户登录,会话将保存:user_id
。
我想要做的是呈现我的视图,具体取决于登录用户的:department
,显示或不显示特定链接。
以下是我在视图中得到的代码,但我正在努力解决如何获取会话信息并从中找到用户部门的问题。
<% if Users.where(id: session[:user_id])[:department] == "Sales" %>
<%= link_to 'New Request', new_request_path %>
<% else nil %>
<% end %>
我知道在控制器或模型以外的地方进行查询是不好的,所以如果你对如何更好地构建这个逻辑有任何建议,我将不胜感激。
答案 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