OK、仕事で 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 が必要になります。OK、購入履歴は、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" を持っているか、nil 以外の has_one :vendor を持っている) の場合、include?(user) に true を返すクラスである可能性があります。 MTIで)。
実際には、必要に応じて gem や cancan を使用してください。ただし、独自のアプリケーション ロジックの設計を切り離す例を考えてみましょう。