Ruby on rails I';我正在尝试确定我的用户';在视图帮助器中的角色,并关注I';我做错了

Ruby 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

我有用于确定给定用户是管理员还是供应商的帮助程序。在助手中,我在数据库中查询各自的角色对象(管理员、供应商等),以便与与用户关联的角色进行比较,但感觉这是确定用户角色的一种倒退方式

我在这里做错什么了吗?我还能做得更好吗?我可能应该提到我正在使用/学习Pundit,因此它可能包含了一种更好的方法来实现这一点。

这是我的密码:

users\u helper.rb

 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没有被维护错误是一个强有力的词。你可能会发现你在不需要的时候询问,等等,但你的方式“有效”。我建议缓存角色,以便您仅从数据库加载它们一次。但是,如果它是一个低容量应用程序,并且不是问题,您可以稍后再解决。角色\模型链接具有额外的']'字符