Ruby on rails I';我正在尝试确定我的用户';在视图帮助器中的角色,并关注I';我做错了
我有用于确定给定用户是管理员还是供应商的帮助程序。在助手中,我在数据库中查询各自的角色对象(管理员、供应商等),以便与与用户关联的角色进行比较,但感觉这是确定用户角色的一种倒退方式 我在这里做错什么了吗?我还能做得更好吗?我可能应该提到我正在使用/学习Pundit,因此它可能包含了一种更好的方法来实现这一点。 这是我的密码: users\u helper.rbRuby on rails I';我正在尝试确定我的用户';在视图帮助器中的角色,并关注I';我做错了,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有用于确定给定用户是管理员还是供应商的帮助程序。在助手中,我在数据库中查询各自的角色对象(管理员、供应商等),以便与与用户关联的角色进行比较,但感觉这是确定用户角色的一种倒退方式 我在这里做错什么了吗?我还能做得更好吗?我可能应该提到我正在使用/学习Pundit,因此它可能包含了一种更好的方法来实现这一点。 这是我的密码: users\u helper.rb 1 module UsersHelper 2 def admin? 3 # Determine whether t
1 module UsersHelper
2 def admin?
3 # Determine whether the user has administrator status within a given event
4 @admin_role = Role.find(1)
5 return true if @user.roles.include? @admin_role
6 end
7
8 def vendor?
9 # Determine whether the user is an approved vendor within a given event
10 @vendor_role = Role.find(2)
11 return true if @user.roles.include? @vendor_role
12 end
13 end
以下是我如何使用模板中的帮助程序:
show.html.erb
1 <% provide(:title, @user.username) %>
2
3 <% if admin? %>
4 <p>Admin</p>
5 <% elsif vendor? %>
6 <p>Vendor</p>
7 <% else %>
8 Something else.
9 <% end %>
1
2.
3.
4Admin
5.
6
7.
还有别的。
9
首先,包含?
方法返回布尔值,因此:
return true if @user.roles.include? @admin_role
等于:
@user.roles.include? @admin_role
除非您需要nil
而不是false
其次,方法名称和代码本身应该非常简单和自描述性,不需要注释。除非你在写公共gem或其他东西时需要自动化文档
关于你的问题,我想你应该如何在你的用户模型中做到这一点:
def admin?
roles.where(id: 1).any?
end
然后您可以在视图中执行
@user.admin?
。用户模型与角色的关联意味着您的用户模型可能同时具有多个角色,例如管理员或供应商
我建议重构用户模型以使用与角色的一个关联,这样用户将只有一个角色
那么user_helper.rb中的helper可能类似于:
def is_a?(user)
roles = { Roles.find(1) => "Admin", Roles.find(2) => "Vendor"}
roles.fetch(user.role) do
"Something else."
end
结束
这将返回具有角色的正确字符串定义的字符串。您可以将其与之进行比较或在视图中使用,如下所示:
<p><%= is_a?(@role) %></p>
它在一行中执行与上面代码相同的操作。这可能比at更好 1) 您的角色实现有点笨重(神奇的数字是什么)-您对角色类做了任何保证它是ActiveRecord类的事情吗?
如果没有,您可以使用(如Sontya所述),它将用户角色保存为用户表中的位掩码。
如果您需要一个更复杂的角色类,您可能想看看,它在概念上与您当前的解决方案类似 无论如何,Rails应用程序中的用户角色都是一个已解决的问题,您不需要编写自己的解决方案(当然,不要因此而气馁,构建自己的解决方案至少是一个很好的学习练习) 2) 检查视图中的角色是一个非常糟糕的主意,尤其是如果您已经在使用pundit 如果要添加新角色,需要查看所有视图并更改If条件以支持新角色。
当视图数量和角色数量增加时,这个问题就会爆发 相反,请在视图中使用权威策略,并检查相应策略对象中的用户角色 例如:
class CompanyPolicy < ApplicationPolicy
def delete?
user.is?(:admin)
end
end
class CompanyPolicy
他认为:
<% if policy(@company).delete? %>
delete link here
<% end %>
删除此处的链接
别忘了在控制器中授权
这样,如果您添加了一个新角色,您只需更改一些策略对象,就可以开始了。试试这个[and[.希望如此helps@Sontya,CanCan没有被维护错误是一个强有力的词。你可能会发现你在不需要的时候询问,等等,但你的方式“有效”。我建议缓存角色,以便您仅从数据库加载它们一次。但是,如果它是一个低容量应用程序,并且不是问题,您可以稍后再解决。角色\模型链接具有额外的']'字符