好的,我在工作中休息了 StackOverflow,然后工作把我叫走了,所以我很快回复了。您必须决定是否要使用 STI,
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |table|
table.string "type"
...
并将您的供应商和客户对象实例存储在您的用户表中,或使用多表继承,您只需简单地拥有
class Vendor < ActiveRecord::Base
belongs_to :user
...
class Customer < ActiveRecord::Base
belongs_to :user
...
如果您曾经拥有特定于您的供应商和/或客户对象的状态数据,例如供应商的销售代表或客户的购买历史,您将需要 MTI。好的,购买历史很可能是与属于_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 :vendor not nil,则该类可能是响应 true 以包含?(用户)的类在 MTI 中)。
在实践中,继续使用 gem,如果你愿意,可以使用 cancan。但是请考虑为您自己的应用程序逻辑解耦设计的示例。