0

楷模:

帐户

  • 这用于存储系统中任何人的登录凭据
  • 它是一种设计模型,具有一个自定义字段“角色”来处理授权
  • 帐户与系统中的某个人(唯一)相关联

员工

  • 这使用一个帐户登录并包含一个 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 中被索引。

但是这种方法有一个问题,如果我添加另一个像客户这样的东西,我需要在 ES 索引中添加一个 customer_id。那我需要重建我的整个索引吗?

替代解决方案 B:

这与上述替代解决方案基本相同,但使 Account 多态,然后它是“负责的”,可以应用于员工和客户。我听说我应该避免使用多态关联,因为它是一种关系气味?

想法?

同样在员工索引视图上,我想过滤/计算未链接到具有方面的帐户的员工。这是否会成为任何解决方案的问题?这将如何设置?

您认为解决此问题的最佳方法是什么?

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。甚至还有 gem 提供了一个简洁的 DSL 来使用它们:

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

于 2013-10-20T20:18:09.087 回答