【问题标题】:How do I search for a model but only if it has at least one child association?我如何搜索模型,但前提是它至少有一个子关联?
【发布时间】:2017-06-14 22:49:21
【问题描述】:

我的 Ruby on Rails 5 (PostGres 9.5) 应用程序中有两个模型。我有

class Machine < ActiveRecord::Base
  has_many :parts

class Part < ActiveRecord::Base
  belongs_to :machine

我想搜索机器对象,所以我有

  @results = Machine.where("name ILIKE ?", "%#{machine_name}%")
                 .order("LOWER(name)")  
                 .paginate(:page => params[:page])

但需要注意的是,我只想返回至少有一个 Part 对象与之关联的对象。我意识到我可以做到

  @results = Machine.joins(:parts)
                 .where("name ILIKE ?", "%#{machine_name}%")
                 .order("LOWER(name)")  
                 .paginate(:page => params[:page])

但我认为这是非常低效的,因为有数以万计的关联。搜索我的 Machine 对象的最有效方法是什么,但前提是它们至少具有一个 Part 关联?

【问题讨论】:

    标签: ruby-on-rails postgresql search associations ruby-on-rails-5


    【解决方案1】:

    更新

    经过一番搜索,这可以很容易地完成

    Machine.joins(:parts)
     .where('some condition')
     .group(:id)
     .having("count('parts.*') > 0")
    

    【讨论】:

    • 如果我有 100 万台带有零件的机器,这个条件 - “.where(id: machine_ids)”会导致 PostGres 执行“WHERE ID IN (id1, ... id1000000)”子句?
    • 是的,确实如此。它不是一个超级优化的版本,它只是在大多数情况下都能很好地工作。
    • 好的,谢谢。让我进行一些测试,看看事情发生的速度有多快。
    • 还有另一种方法,那就是使用计数器缓存。 yerb.net/blog/2014/03/13/…
    • @Dave 我用更好更快的解决方案编辑了答案,希望它有效。
    猜你喜欢
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-07
    相关资源
    最近更新 更多