【问题标题】:Can't make complex SQL request in rails无法在 Rails 中发出复杂的 SQL 请求
【发布时间】:2021-03-04 19:44:54
【问题描述】:

我有两个独立的模型 MarketOrderOnlineOrder

两个模型没有任何关系,但需要显示在一个表格中。

需要排序和分页。简单的解决方案是:

orders = (MarketOrder.all + OnlineOrder.all).sort_by(&:created_at).paginate(per_page: 50, page: params[:page])

这很好用,但随着订单数量的不断增长,它不适合。查询所有记录会导致性能大幅下降。如何正确缩小此类查询?谢谢

更新

模型没有完全相同的列,但共享一些需要在我的视图文件中显示的常见列。

MarketOrder(
  id: integer, 
  user_id: integer, 
  service_fee_amount: decimal, 
  status: string, price: decimal, 
  created_at: datetime, 
  updated_at: datetime..
)
OnlineOrder(
  id: integer, 
  user_id: integer, 
  category: string, 
  comment: text, 
  status: string, 
  price: decimal, 
  created_at: datetime, 
  updated_at: datetime...
)

请注意,这两个模型都是独立的,并且两者中的 ID 都是 1,2,3... 1,2,3...

但是每个模型都与第三个模型用户(belongs_to has_many)有关系,并且每个表都包含 user_id。

根据sort_by(&:created_at).paginate(per_page: 50, page: params[:page]) 50 最近的订单将使用 jbuilder 准备并发送到反应组件。要获得接下来的 50 个订单,将再次向后端发出请求。

【问题讨论】:

  • 请更新数据库表结构。
  • 你的这两个模型有相同的属性吗?
  • 以上用户正在寻找的是一种帮助您创建“UNION”的方法。 Schema 对此很重要,但您能否具体告诉我们您在视图中使用了哪些列 (methods)?
  • 在两个不同的模型上调用.all,然后将结果拼凑在一起,如果这些表增长到不平凡的大小,将会变得非常昂贵。
  • 不完全是您要问的问题,但如果您可以编写所需的 SQL,将它放在数据库视图中然后在其周围包装一个只读视图可能是有意义的。

标签: ruby-on-rails rails-activerecord arel


【解决方案1】:

你可以创建一个多态表Order,应该有字段order_link_type(字符串)、order_link_id(整数)和order_created_at(日期时间)

class Order < ApplicationRecord
  belongs_to :order_link, polymorphic: true, optional: true
end

class MarketOrder < ApplicationRecord
  has_one :order, as: :order_link, dependent: :destroy
  after_save :create_order
  private
  def create_order
    return if order

    build_order(order_created_at: created_at)
  end
end


class OnlineOrder < ApplicationRecord
  has_one :order, as: :order_link, dependent: :destroy
  after_save :create_order
  private
  def create_order
    return if order

    build_order(order_created_at: created_at)
  end
end

现在你可以做...

orders = Order.all.sort_by(&:order_created_at).paginate(per_page: 50, page: params[:page])

您可以使用order.order_link.user_id 访问视图中的字段,对于仅存在于一种类型或订单链接上的字段,您可以有条件地检索值,例如order.order_link.try(:comment) 您可能希望delegate 到@987654329 @class 一些字段,所以你可以参考order.user_id

【讨论】:

    猜你喜欢
    • 2020-04-30
    • 1970-01-01
    • 2019-11-30
    • 2016-09-19
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    相关资源
    最近更新 更多