所以我想做的是根据current_user
的角色进行重定向。
这就是我所拥有的:
path = case current_user.roles.where(:name => "vendor")
when :vendor
dashboard_path
when :guest
home_path
else
home_path
end
redirect_to path
我正在使用cancan
,我知道的唯一方法是找出用户的角色,要么current_user.has_role? :admin
还是current_user.roles.where(:name => role_name)
。
鉴于这些限制(或告诉我另一种方法来确定用户的角色),我如何让这个案例陈述起作用?
修改1
假设我正在检查多个角色,而不仅仅是我在这里的2个角色 - 可能是4个或5个。
修改2
要清楚,这是我目前的设置。
我正在使用Devise,CanCan& Rolify。 Rolify允许用户拥有多个角色,但我的应用程序不具备该用例。用户只有一个角色。它们可以是vendor, buyer, guest, superadmin
。
如果他们是vendor
,他们只能看到属于他们的dashboard_path
。他们看不到任何属于其他任何人的vendor storefront
。他们也不应该看到其他供应商的产品。因此,一旦他们登录,他们的root_path
应该是dashboard_path
而不是home_path
,这就是每个其他角色的root_path
。
如果他们是guest
,他们可以看到除价格之外的所有东西 - 我已经有了这个逻辑。我这样做了:
if user.has_role? :guest
can :read, [Product, Vendor, Banner]
cannot :view_prices, Product
end
然后在我看来,我刚做了类似的事情:
<% if can? :view_prices, Product %>
<div class="price pull-right">
<%= number_to_currency(@product.price) %> ea
</div>
<% else %>
<span class="no-price pull-right"><%= link_to "Log In To See Price", login_path %></span>
<% end %>
所以,基本上......我的真正目标是根据用户的角色尝试更改root_path
。我基本上试图在this question上实现答案。
答案 0 :(得分:6)
最终答案 (适用于早期的导师,见下文)
如果您的用户只能拥有一个角色,我会说您当前的实施并不完全合适。但是,如果您确实需要保留此实现,则可以执行以下操作:
class User < ActiveRecord::Base
# this will return the name of the first (so the only one)
# role that your user has, or nil.
def role_name
roles.first.try( :name )
end
end
所以现在你的案例陈述会起作用:
path = case current_user.role_name
when 'vendor' ; dashboard_path
when 'guest' ; home_path
when 'foo' ; bar_path
else home_path
end
我仍然鼓励您将案例陈述包装在帮助程序中,以便重用并更容易维护。
更早的回答
我不确定我理解你的问题,但我认为你不需要这里的案例陈述:
redirect_to (current_user.has_role? :vendor ? dashboard_path : home_path)
另一种方法是将部分责任推送到用户类(或演示者):
class User < ActiveRecord::Base
def home_page
# here some logic to return a symbol like :home or :dashboard,
# depending on your roles implementation. Your User could even use
# a state machine to do this, or have multiple decorators.
end
end
然后带帮助者
def home_path_for( user )
case user.home_page
when :home ; home_path
when :dashboard ; dashboard_path
when :foo ; bar_path
else home_path
end
end
第一次编辑
如果您的用户一次可以拥有多个角色,我会说案例陈述不合适。 case
是一个分支声明,仅当您在一组可能的结果中只有一个且只有一个输入和一个且只有一个结果时才适用。
因此,您必须将角色列表减少到中间状态,例如:
DASHBOARD_ROLES = [:vendor, :admin]
CLIENT_ROLES = [:client, :prospect]
BASIC_ROLES = [:logged_visitor]
if (DASHBOARD_ROLES & user_roles).any?
:admin_dashboard
else if (CLIENT_ROLES & user_roles).any?
:client_dashboard
# additionnal, different logic is possible
else if (BASIC_ROLES & user_roles).any? && user_logged_in? && user_roles.first != :prospect
:logged_dashboard
else
:home
end
这是一种完全不同的逻辑。
答案 1 :(得分:1)
首先,如果可能,您可能需要解决用户具有多个角色的情况。
假设用户有一个角色(虽然我们可以根据需要添加更多条件)你能考虑一个哈希吗?
像 -
path = {:vendor => dashboard_path, :guest => home_path} [current_user.active_role] || default_path
我做了一些假设 -
current_user.active_role
可以是用户的当前角色,您可以根据该角色重定向答案。default_path
是不言自明的。