【问题标题】:The rails way to create a complex user structure创建复杂用户结构的 rails 方式
【发布时间】:2012-04-23 20:44:08
【问题描述】:

我是 Rails 的新手,我想知道我应该如何做这样的事情:

我正在创建一个包含两个主要用户组的应用,我们称他们为客户和供应商。

我应该如何实现这一点,记住这些相似点和不同点:

区别:

  • 从业务角度来看,这两个群体是分开的,一般客户都是从供应商那里购买的。
  • 它们主要与不同的模型相关联,供应商 90% 的时间使用应用程序的后端,而客户仅使用前端。
  • 用户帐户管理完全不同

相似之处:

  • 对于两者我都想使用一些基于角色的授权解决方案(例如declarative authorization
  • 他们都登录了
  • 在极少数情况下,两者通过相同的控制器/视图与相同的模型进行交互

同时保持简单和清洁的最佳解决方案是什么?一种与客户和供应商模型相关的胖用户模型?具有重复登录逻辑的单独模型(它如何与声明性授权一起使用)?单表继承(又是声明式授权呢)?

【问题讨论】:

  • 您正在为大多数人单独解决的多个问题提供解决方案。您正在尝试进行基于角色的授权,并在您的数据模型中拥有客户和供应商数据实体。不是说不好,只是其他程序员的体验可能不一样。

标签: ruby-on-rails database authentication


【解决方案1】:

我会创建一个User 类来处理诸如授权之类的事情以及您系统的所有用户都拥有的任何其他基本功能。然后创建独立的CustomerVendor 类,它们继承自User 并拥有自己的业务逻辑。 Rails 中的 STI 让它变得非常简单 - 创建一个 type 列,它会自动填充类名。

您可以使用像CanCan 这样的gem 来隔离User 的每种类型的权限。

【讨论】:

  • 我同意。在 User 和 Role 之间添加 Role 类和多对多。我将其命名为 RoleMembership。我在 ApplicationController 的 before_filter 中进行授权。我还有一张表,其中角色可以访问哪些控制器。
  • 谢谢,我会这样做,希望 STI 不会在使用 CanCan 或声明性授权等 gem 时出现问题
【解决方案2】:

好的,我在工作中休息了 StackOverflow,然后工作把我叫走了,所以我很快回复了。您必须决定是否要使用 STI,

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |table|
      table.string   "type"
...

并将您的 Vendor 和 Customer 对象实例存储在您的 users 表中,或者使用多表继承,您只需在其中简单地拥有

class Vendor < ActiveRecord::Base
  belongs_to :user
...
class Customer < ActiveRecord::Base
  belongs_to :user
...

如果您拥有特定于您的供应商和/或客户对象的状态数据,例如供应商的销售代表或客户的购买历史,您将需要 MTI。好的,购买历史很可能是连接到 belongs_to :customer 的其他表,但是当用户可以是供应商时,让连接的记录 belongs_to :user 看起来很尴尬。

现在,为了配合访问控制,...我已经实现了一个 access_control_items 表,

class CreateAccessControlItems < ActiveRecord::Migration
  def change
    create_table "access_control_items", :force => true do |table|
      table.timestamps
      table.string   "controller"
      table.string   "action"
      table.string   "group_type", :null => false
      table.integer  "group_id",   :null => false
    end
  end
end

关键是我将角色的成员资格与访问控制分离,并使其具有多态性,因此它可以是任何具有 include?(user) 方法的对象的成员资格。我的应用程序控制器之前的方法将当前登录的用户发送到包含?与控制器和操作匹配的任何 access_control_items 引用的组的方法。

所以该组可以指向某个 ActiveRecord 类的实例,如果用户是供应商(在 STI 中具有 type = "Vendor" 或 has_one ,则该类可能是响应 true 以包含?(用户)的类:供应商在 MTI 中不为零)。

在实践中,继续使用宝石,如果您愿意,可以使用。但请考虑为您自己的应用程序逻辑解耦设计的示例。

【讨论】:

    猜你喜欢
    • 2015-05-22
    • 1970-01-01
    • 2018-12-12
    • 2011-10-06
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多