0

モデル:

アカウント

  • これは、システム内のすべてのユーザーのログイン資格情報を保存するために使用されます
  • これはデバイス モデルであり、承認を処理するカスタム フィールド「ロール」が 1 つあります。
  • アカウントは、システム内の誰かに (一意に) リンクされています

従業員

  • これはアカウントを使用してログインし、account_id FK を含みます

クライアント

  • これはアカウントを使用してログインし、account_id FK を含みます

関係:

アカウントhas_one :employeehas_one :client.

従業員とクライアントそれぞれbelongs_to :account

クエリ:

次のような質問に答えられるようになりたいです。

「リンクされていないすべての従業員アカウントを表示してください」

  • これは、次の生のクエリによって解決されました。

    find_by_sql("select * from accounts where id not in (select account_id from employees)")

  • 上記の実装は、リンクされていないすべてのアカウントを多くのテーブルにまたがって表示したい場合に醜くなりますが、これは確かにやりたいことです。

代替ソリューション:

代わりにアカウント テーブルに employee_id と client_id の両方が含まれるように設定を変更する必要がありますか?

次に、各 FK で nil をチェックするだけで、従業員にリンクされた、クライアントにリンクされた、または完全にリンクされていないアカウントのリストを取得するのは簡単です。FK は、elasticsearch でもインデックスを作成できます。

ただし、このアプローチには問題があります。customer などの別のものを追加する場合、ES インデックスに customer_id を追加する必要があります。その場合、インデックス全体を再構築する必要がありますか?

代替ソリューション B:

これは基本的に上記の代替ソリューションと同じですが、アカウントをポリモーフィックにすると、「説明可能」になり、従業員とクライアントの両方に適用できます。多態的な関連付けは避けるべきだと聞きましたが、それは関係のにおいがするからですか?

考え?

また、従業員インデックス ビューで、ファセットを持つアカウントにリンクされていない従業員をフィルター処理/カウントしたいと考えています。これは、いずれかのソリューションで問題になりますか? これはどのように設定されますか?

これを解決する最善の方法は何だと思いますか?

4

1 に答える 1

0

少なくともこの時点では、最初の解決策は悪くないように聞こえます (おそらく、Ypu から提供されたよりも多くの情報をお持ちです:))。

あなたは SQL クエリに直面しているようです。悪い例を選んだのかもしれません。クエリfind_by_sqlは、次のように OUTER JOIN を使用して記述できます。

Account.joins( "LEFT OUTER JOIN employees ON employees.account_id = accounts.id" ).where("clients.id" => nil)

または:

Account.where("NOT EXISTS( SELECT 1 FROM clients c where c.account_id = accounts.id )")

これらのクエリは基本的に同じです (同じクエリ プランを生成します)。

クエリが非常に複雑になる場合、Postgres にはCTEと呼ばれるそれらを整理する優れた手段があります。それらを使用するための適切な DSL を提供する gem もあります。

http://reefpoints.dockyard.com/2013/09/06/postgres_ext-adds-rank-and-common-table-expressions.html

于 2013-10-20T20:18:09.087 に答える