我们有两个属于公司的模型:客户发票和供应商发票。目前他们有自己的索引页;在这些页面上生成用于分页/排序的集合就像current_company.customer_invoices
一样简单。
class CustomerInvoice < ApplicationRecord
belongs_to :company
end
class VendorInvoice < ApplicationRecord
belongs_to :company
end
class Company < ApplicationRecord
has_many :customer_invoices, -> { order(due_date: :desc) }
has_many :vendor_invoices, -> { order(due_date: :desc) }
end
我们现在需要创建一个共享索引页面,对两种发票进行分页和排序。 STI 似乎是显而易见的解决方案,但由于它们在功能上非常不同,并且在其模式列中具有最小交集,因此它给我们留下了不好的用例印象。除了加载所有记录并在内存中对它们进行排序/分页之外,还有其他选择吗?
class Company
def invoices
(customer_invoices + vendor_invoices)
end
end
class InvoicesController < ApplicationController
def index
@invoices = current_company
.invoices
.sort_by(&:due_date)
.page(params[:whaveter_page])
end
end
随着发票数量的增加,这将产生非常糟糕的内存性能:( 。
最佳答案
为了给您最好的答案,需要了解数据库的结构、用例等。
但是您可以考虑以下两种方法:
创建单独的表来存储两个模型的数据。此类表应仅包含过滤、排序和组合列表上显示的数据所需的列。当然还有对受人尊敬的表中原始行的引用。对于这样的表,它非常简单,您只需查询该表即可。主要缺点是现在在创建或更新发票时需要写入两个表。但是生成组合索引将会非常快。从技术上讲,您可以仅将所有索引移至该表并进行其他数据库优化。
您可以使用
UNION
语句将两个表的结果合并为一个。您需要从两个表中选择具有相同类型的相似列。它会比第一个解决方案慢,但优点是您不必维护额外的表。它将根据需要创建。使用事件记录编写联合语句可能有点困难
关于ruby-on-rails - 如何在没有 STI 的情况下从两个单独的表创建 ActiveRecord 集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50534682/