【问题标题】:Rolify: Validate roles with complex functionality inside the User modelRolify:在用户模型中验证具有复杂功能的角色
【发布时间】:2017-08-15 06:33:34
【问题描述】:

我花了四天时间尝试实现此角色验证,但没有成功,我不知道目前是否有任何方法可以使用 rolify 执行此行为。这是我遇到的情况的一个简单示例:

假设我有 3 种类型的角色:

  • 管理员
  • 开发者
  • 客人

用户既可以是管理员也可以是开发人员,但不能同时是访客。

来宾既不能是管理员也不能是开发人员。

我希望用户能够在用户注册时设置他们的角色,所以我需要在创建用户之前验证此行为,如果它无效,则注册应该失败并且不应创建用户。

我已经阅读了很多试图达到类似结果的指南,至少对于表单提交而言,但没有关于这种类型的验证的解释。

提前致谢!

更新: 我一直在寻找一些方法来实现这一点,这就是我在这段挣扎中的思路。

首先:接收选择的角色作为输入,并在与该角色对应的用户模型中创建一个虚拟属性,以便参数看起来像这样(简化)

:params => { :user => {:email, :password, :roles => ["admin", "developer", "guest"]}}

如果所有角色都被选中,并且

:params => { :user => {:email, :password}}

如果没有选择任何角色。

第二:用这个虚拟属性做任何类型的验证(简化)

Class User < ApplicationRecord
  attr_accessor :roles
  validate :roles_valid

  def roles_valid
    # Define custom validation
  end
end

第三:如果记录通过所有验证,创建用户,然后在registrations#new操作中分配角色

我认为这种方法可行,但我现在对虚拟属性有一些问题,而且它似乎与从表单接收的角色参数无关。我想我仍然不明白虚拟属性是如何工作的,所以我希望有人能帮我弄清楚这一点。

【问题讨论】:

  • 您如何知道用户在尝试注册时是否无效?
  • @chumakoff 我需要的是模型内部的某种用户验证,这将能够检查通过表单发送的角色是否是一组有效的角色,以及验证是否失败,回滚并向用户显示错误。理想的情况是在 User 模型中进行这种验证,但我还没有找到一种方法来验证旨在转到另一个模型(在本例中为角色模型)的参数。

标签: ruby-on-rails forms validation devise rolify


【解决方案1】:

我现在明白了!我在更新中添加的过程是正确的,所以我将简要介绍如何正确实现这一点。

目标:验证用户模型内的复杂功能。这必须在 User 模型中完成,因为必须检查所有添加的角色,而不是单独检查每个角色

第一步:如果您的应用将使用的角色是静态的,那么您必须首先使用特定角色填充您的角色表。为此,我将在 Stack Overflow 的另一个问题中留下一篇文章,深入解释这个过程:

Defining Roles with Rolify

第二步:修改您的注册表单。为了获得用户选择的角色,我们必须首先添加一些与第一步定义的角色相对应的复选框。这是一个简单的代码。

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <!-- ADD HERE ALL YOUR REGISTRATION INPUTS -->
  <% Role.all.each do |role| %>
    <%= f.checkbox :input_roles, {multiple: true}, role.name, nil %>
    <%= role.name %>
  <% end %>
<% end %>

这样做会生成所有必要的复选框,并将结果存储在变量中

params => {:user => { :input_roles => [] }}

重要提示!如果用户没有选择任何角色,那么变量input_roles 将不会被定义!您必须在验证中检查这一点。 另外,不要将变量的名称更改为 roles,我犯了这个错误,并在尝试修复我遇到的所有错误时经历了地狱。如果有兴趣查看我所经历的一切,这里是我创建的问题的链接:

https://github.com/RolifyCommunity/rolify/issues/446

第三步:由于您要向表单添加一个新参数,因此您还必须将它包含在您的强参数中。由于这个变量是一个数组,你必须在你的强参数中明确地定义它:

如果您使用的是设计:

devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :password, :password_confirmation, input_roles: [])

如果您不使用设计:

params.require(:user).permit( :email, :password, :password_confirmation, input_roles: [])

第四步:好的,现在input_roles 参数被传递到我们的User 模型中。但是,现在我们需要找到一种方法来验证里面的值。由于这个参数不是我们用户模型的一部分,我们必须创建一个虚拟属性才能使用这个参数。所以我们只需将其命名为与传递给模型的参数相同,如下所示:

Class User < ApplicationRecord
rolify
attr_accessor :input_roles

现在,当您想要访问用户选择作为角色的值时,您只需在您的用户模型中执行此操作:

self.input_roles.to_a # => ["admin", "developer", "guest"] If the user selected all roles

现在您可以使用这些信息进行各种验证!希望这可以帮助! 如果有人知道更清洁的方法,请告诉我。我浏览了所有我能偶然发现的东西,但没有给出答案。至少,验证是在模型内部完成的,而不是在控制器内部完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    相关资源
    最近更新 更多