【问题标题】:Add sorting scope to chain without hitting database twice (Rails, ActiveRecord)将排序范围添加到链而无需两次访问数据库(Rails,ActiveRecord)
【发布时间】:2020-03-11 01:17:28
【问题描述】:

我有一个链式范围查询,它检查标记项目的标签并将它们从“可用”列表中删除。但是,此范围被固定到“可见”范围:

scope :visible, -> { where("rfid_tags.location_id NOT IN (SELECT warehouses.id FROM warehouses WHERE warehouses.deleted_at IS NULL AND warehouses.hidden = 't') OR rfid_tags.location_type = 'Listing'") }
scope :available, -> { not_selected.visible.without_flags }
 scope :without_flags, -> { joins("LEFT OUTER JOIN flags ON flags.rfid_tag_id = rfid_tags.id").where(flags: { id: nil })}

我正在尝试对可见标志进行排序,以便标记的项目位于列表的末尾;一位同事建议我使用类似的东西:

scope :available, -> { not_selected.visible.without_flags.ordered }
scope :ordered,  -> (recs) { recs.order('flags.rfid_tag_id NULLS FIRST') } 

并将其附加到 :visible,但我认为我不太了解如何使用 recs 概念(研究如何传入参数)?尝试在 :ordered 范围上加入标志会因为多次调用标志表而出错。我正在使用 Rails 4/postgresql。如何使用连接表数据正确结算排序?

【问题讨论】:

    标签: postgresql ruby-on-rails-4 activerecord scope


    【解决方案1】:

    您可以将订单添加到with_out_flags 范围。

    scope :without_flags, -> { 
      joins("LEFT OUTER JOIN flags ON flags.rfid_tag_id = rfid_tags.id")
        .order('flags.rfid_tag_id NULLS FIRST')
        .where(flags: { id: nil })}
    

    然后,如果您需要更改顺序,您可以使用reorder()。这将使先前定义的订单查询无效,并在重新排序子句中使用您的新查询。

    如果您仍然收到有关多次引用标志表的错误,您可以在连接中使用表别名并引用它。

    scope :without_flags, -> { 
      joins("LEFT OUTER JOIN flags f ON f.rfid_tag_id = rfid_tags.id")
        .order('f.rfid_tag_id NULLS FIRST')
        .where(flags: { id: nil })}
    

    【讨论】:

    • 我虽然这可能会导致其他问题,因为我必须让它在:visible 上独立工作,但我意识到我可以创建一个替代的更窄的:visible_in_cart 范围来独立链接:without flags ,最终在 UI 中表现更好。有时越简单越好。感谢您的帮助!
    猜你喜欢
    • 2023-03-05
    • 2021-12-28
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多