查找在其数组列

时间:2016-10-12 10:29:15

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

所以我有食谱表和食材表。 在食谱表中有一个成分列,列出了每种食谱所需的所有成分的ID。

我想搜索该数组以查找它是否包含一种特定成分。

我发现include?方法适用于以下情况:

Recipe.find(35).ingredient.include? params[:ingredient]

我试图用where方法来完成这项工作:

Recipe.where('ingredient.include?', params[:ingredient].to_i)

看起来很简单,但它不起作用。我尝试删除逗号,结果相同。

我无法找出合适的语法。

2 个答案:

答案 0 :(得分:1)

只是抬头,保持带有一系列ID的列通常不是最好的解决方案!

首选方法是Rail has_and_belongs_to_many关联,它使用连接表(ala ingredients_recipes)来存储关系。

在许多数据库中存储数组中的ID是非首发,因为它不受支持。在Postgres中使用@>包含运算符是可能的,但是你失去了关系完整性(外键约束)的好处,并且牺牲了Rails和其他ORM的自动管理。

但这是一个开放的建筑问题;如果您正在处理大量数据(数百万行),那么数组可能会带来性能优势(请参阅Using postgres arrays in relations)。通常不值得放弃Rails'虽然自动管理协会!

答案 1 :(得分:0)

您可以使用any

查询数组
Recipe.where('WHERE ? = ANY (ingredient)', params[:ingredient])

虽然在这里使用数组并不理想。有些情况下,一个简单的数组是适合的,但是当你应该使用正确的关系时却不适合。

class Recipe
  has_many :recipe_ingredients
  has_many :ingredients, though: :recipe_ingredients
end

class RecipeIngredient
  belongs_to :recipe
  belongs_to :ingredient
end

class Ingredient
  has_many :ingredients
  has_many :ingredients, though: :recipe_ingredients
end

这将允许您从两端进行查询:

Recipe.joins(:ingredients)
      .where(ingredients: { name: ['basil', 'thyme'] } )
Ingredient.joins(:recipes)
      .where(recipes: { main_type: 'dessert' } )

除了将数据附加到recipe_ingredients表(例如数量(has_and_belongs_to_many无法实现))之外,它还可以让您直接查询连接表,这可能非常有用。< / p>

为什么不使用数组?

因为ActiveRecord不是围绕使用数组存储关联而构建的。您基本上失去了ActiveRecord关联的所有好处,几乎没有或没有性能优势。您不能使用外键约束来确保数据库中的数据完整性。