2017-04-22 13 views
0

私はそうのような役割を持つユーザー、持っている場合:サブクラスモデル、どのようにActiveRecordモデルをスコープしますか?

class User < ApplicationRecord 

class Manager < User 

    def after_initialize do |u| 
     u.role = User.roles[:manager] if u.new_record? 
    end 

が、これは自動的に役割を果たしているとマネージャーのすべてのインスタンスを許可しますが。しかし、私がManager.allのような電話をすると、初期化されていないので、これは私にユーザーのすべてのインスタンスを返すでしょう。Manager予想される動作は、ロールマネージャを使用するすべてのユーザーを受け取ることです。これについてはどうすればいいですか?それでもただサブクラスを使用する場合は、管理者ロールを持つすべてのユーザー を呼び出したいとき

答えて

1

アクティブレコードモデルをサブクラス化する場合は、ユーザークラスにtype列を追加して、単一テーブル継承を実装することができます。

Docs

これは、マネージャオブジェクトが自動的Managerインスタンスの代わりに、ユーザーインスタンスのように初期化することができるようになります。

Manager.allも呼び出すことができますが、ロール関係の必要性は幾分なくなります。

個人的には、ロールの関係を維持するか、Userモデルをサブクラス化することを選択しますが、両方を選択することはありません。

+0

このルートを使うと、基本的に 'user.manager? 'のようなenumを使って得られる無料のヘルパーメソッドが失われてしまいます。 – Strawberry

+0

ええ、ここのさまざまなソリューションはそれぞれ独自のトレードオフを持っています。 単一テーブルの継承は、同じ情報をカプセル化するが、その情報で操作するときの動作が異なる多くのクラスがある場合に適しています。 ユーザークラスが単一の役割しか持たないことがわかっている場合、ユーザークラスの列挙型はロールを示すことができます。 ユーザーが多数の役割(マネージャとスーパーバイザ)を持つことができる場合は、多人数参加型の関係を「ロール」モデルと組み合わせて実装する方が適切かもしれません。 enumによって与えられたヘルパーメソッドを取得するには、それらを自分で記述することができます。 – brendandeere

1

scope :manager, -> { where(role: "manager") } 

その後、ユーザーモデルにこれを追加し

この

User.manager 

を行いますサブクラスでデフォルトスコープにする

class Manager < User 
    default_scope { where(role: "manager") } 
end 
関連する問題