【问题标题】:Get users which has specific role ONLY - Rolify仅获取具有特定角色的用户 - Rolify
【发布时间】:2019-12-11 10:37:35
【问题描述】:

有一个下拉菜单显示销售代表列表,定义如下。

<%= f.select :sales_rep_id,
          User.with_role(:sales_rep).order(:email).map { |u| [u.email, u.id] },
          { include_blank: true },
          class: 'form-control' %>

sales_rep 用户还可能具有其他角色,例如开发人员。

我还需要隐藏具有开发者角色的销售代表用户

类似

User.where.not(has_role?(:developer)).with_role :sales_rep

关于如何实现这一点的任何想法。

【问题讨论】:

  • 您能描述一下用户和角色之间的关系吗? with_role 作用域生成的 SQL 是什么?
  • 关系是销售代表也可以是开发人员。我需要选择不是开发人员的销售代表。为 with_role 执行的查询如下 SELECT "users".* FROM "users" INNER JOIN "users_roles" ON "users_roles"."user_id" = "users"."id" INNER JOIN "roles" ON "roles" ."id" = "users_roles"."role_id" WHERE (((roles.name = 'sales_rep') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))))

标签: ruby-on-rails ruby-on-rails-4 rolify


【解决方案1】:

这不是最佳答案,但您可以根据需要使用它。

User.with_role(:sales_rep) - User.with_role(:developer)

【讨论】:

    【解决方案2】:
    non_developers = User.enabled.order(:email).without_role(:developer)
    sales_reps = non_developers.with_role(:sales_rep)
    

    工作就像一个魅力......

    【讨论】:

    • 这有点奇怪不是吗?您不接受我的回答以接受您自己的回答。我确实花时间帮助您找到答案,您甚至没有为我的答案投票。此外:您的答案不完整,您没有定义without_role,因此任何读者仍然需要阅读我的答案才能理解它。
    【解决方案3】:

    所以

    developers = User.with_role(:developer)
    sales_people = User.with_role(:sales_rep)
    

    为了尽可能有效地从另一组中排除一组,我会执行以下操作:

    User.with_role(:sales_rep).where.not(id: User.with_role(:developer).select(:id).map(&:id))
    

    这应该返回想要的集合,现在我们可以稍微改进一下:

    在你的User 类中添加一个方法

    def self.without_role(role)
      where.not(id: User.with_role(role).ids)
    end
    

    请注意,User.pluck(:id) 或短版本 .ids 的结果与 User.select(:id).amp(&amp;:id) 相同,但效率更高,因为它不会实例化完整的 User 对象。

    然后你可以写

    User.without_role(:developer).with_role(:sales_rep)
    

    【讨论】:

    • 第一个工作正常,但改进后的代码不起作用。如果我在 self.without_role(role) 方法中运行 User.with_role(role).pluck(:id) ,它将返回一个空数组。
    • 当我在 self.without_role(role) 方法中运行 User.with_role(role).pluck(:id) 时运行的查询如下。 User.with_role(:developer) 用户负载 (0.6ms) SELECT "users".* FROM "users" INNER JOIN "users_roles" ON "users_roles"."user_id" = "users"."id" INNER JOIN "roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users"."enabled" = $1 AND (((roles.name = 'sales_rep') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) AND (((roles.name = 'developer') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["enabled", "t"]]
    • 您使用的是哪个版本的 Rails?因为pluck 已经更改/改进了版本?我正在使用 rails 4.2.11.1 进行测试(因为您的标签显示 ruby​​-on-rails-4)
    • 哈,我刚刚了解到还有一个更短的版本:在 rails 4 中,您也可以写 .ids,它会做同样的事情。 Weird pluck 也应该在 rails 3 中工作,所以仍然好奇你使用的是哪个版本。
    • 哦,也许不是pluck,也许是命令?如果你写User.without_role(:developer).with_role(:sales_rep)会发生什么?
    猜你喜欢
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    相关资源
    最近更新 更多