带有多个记录的Rails复杂查询设置

时间:2018-08-09 00:40:15

标签: sql ruby-on-rails postgresql

我试图弄清楚如何在Rails中执行查询,在Rails中,另一个查询返回了多个ID。我有一个包含通过内容包含许多化合物的食物表。我想做的是获取与原始食物至少共享一种化合物的食物清单。目前,我有以下内容:

要从最初的食物中提取化合物,我要这样做:

def set_food
      @food = Food.includes(:compounds).find(params[:id])
    end

设置食物和化合物,我可以通过调用每个内容来输出所有内容并显示每种食物中的化合物。因此,下一步我不确定该怎么做是如何从内容表中获取所有food_id,其中compound_id等于上述返回的原始内容中的其中一个(希望这是有道理的)。所以像这样(我知道这是不对的)

def show
    @pairs = Food.joins(:contents).where(contents: {compound_id: @food.contents.compound_id})
  end

任何帮助将不胜感激,尝试使用谷歌搜索答案,但甚至不能确定谷歌如何找到正确的方向

2 个答案:

答案 0 :(得分:1)

您已经渴望在获取@food的同时加载化合物,因此可以分两个步骤进行操作:

首先,获取与您的原始食物相关的所有有趣的化合物ID:

compound_ids = @food.compounds.pluck(:id)

我认为与AR关系您甚至应该能够做到:

# worth the try
compound_ids = @food.compound_ids

第二步,您几乎使用了之前的相同查询:

@pairs = Food.joins(:contents).where(contents: { compound_id: compound_ids })

{ compound_id: [array] }应该转换为SQL IN语句,例如:contents.compound_id IN (1,2,3)

这是最简单的方法,无需进入子查询等。

答案 1 :(得分:1)

您还可以使用以下子查询来执行此操作:

@pairs = Food.joins(:contents).where(contents: { compound_id: @food.compounds.select(:id) }) 然后,您会收到类似以下内容的查询:

SELECT `foods`.* FROM `foods` INNER JOIN `contents` ON `contents`.`food_id` = `foods`.`id` WHERE `contents`.`compound_id` IN(SELECT id FROM compounds WHERE ...)

如果您有很多ID,这可能会更好地提高性能。如果您使用@ food.compound_ids的pluck或@ food.compounds.ids,则可以获得大量ID,并将其传递到查询中,这会变得非常慢。