0

アプリケーションにモデル(エージェントと呼ぶことができます)があり、モデルミッション(1つ以上のエージェントに割り当てられる可能性のあるミッションを表すモデル)と多対多の関係があり、エージェントがミッションを受け入れることができます:

class Agent < ActiveRecord::Base
    has_many :assignments
    has_many :missions, :through => :assignments
end

class Assignment < ActiveRecord::Base
    belongs_to :agent
    belongs_to :mission

    attr_accessible :accepted
end

class Mission < ActiveRecord::Base
    has_many :assignments
    has_many :agents, :through => :assignments
end

ここで、次の要件を使用して、すべてのエージェントに一度に割り当てられるミッションを作成できるようにしたいと思います。

  1. 「グローバル」ミッションはすべてのエージェントに割り当てられていますが、それぞれ個別に受け入れることができます
  2. 「グローバル」ミッションは、グローバルミッションの作成後に作成されたエージェントにも適用されます。
  3. 新しいエージェントが作成されるたびに(すべてのグローバルミッションを割り当てるために)新しい割り当てモデルを作成したくないし、新しいグローバルミッションが作成されるたびに既存のすべてのエージェントに割り当てを作成したくない。
  4. 特定の(または複数の)エージェントに割り当てられた既存のミッションは、グローバルミッションに簡単に変換できます。
  5. エージェントが与えられた場合、私は彼のすべての割り当て(グローバルおよび特定)を1回の呼び出しで取得し、可能であれば、配列ではなくリレーションとして取得したいと考えています。

グローバルミッションと非グローバルミッション用に別々のテーブルを作成せずにこの機能を実現するための優れた設計(dbとモデルの両方)は何でしょうか?

ありがとう!

アリエル

4

1 に答える 1

2

ミッションにis_globalフラグを追加するだけです。

次に、受け入れるミッションのリストを取得するときに、特定のエージェントに割り当てられていて受け入れられていないすべてのミッションと、特定のエージェントに割り当てられていないすべてのグローバルミッションを探すだけです。

エージェントがグローバルミッションを受け入れたら、割り当てレコードを作成し、acceptedをtrueに設定します。

エージェントがミッションから自分自身を削除できる場合は、割り当てレコードを破棄するだけです。

すべてのミッションを取得する

2つの異なるケースを調べるには、利用可能なすべてのミッションのフェッチを強化する必要があります。最初のケースは割り当てられたミッションであり、2番目のケースはグローバルであるが割り当てられていないミッションです。

Mission.includes(:assignments)
        .where("missions.is_global = true or assignments.agent_id = ?", agent_id)

私はすぐにテストできるrubyenvを持っていませんが、それが正しくない場合は近いです:)

ボーナス

割り当てがグローバルであるか定期的であるかを気にせずに、すべての割り当てを照会できます。

assignments = agent.ssignments.where(accepted:true)

アップデート

私のクエリがうまくいかない場合、または別のルートに行きたい場合は、常に他のソリューションがオンラインにあり、メタウェアまたはスクイールジェムが役立ちます。

于 2013-03-19T22:08:04.223 に答える