我有一个包含多个Ingredients
的Recipe
class Recipe < ApplicationRecord
has_many :ingredients
end
class Ingredient < ApplicationRecord
belongs_to :recipe
end
我可以找到包含任何名称与搜索查询相似的成分的食谱,q
。
Recipe.joins(:ingredients).where('lower(ingredients.name) LIKE ?', "%#{q}%")
结果如下:
Recipe.search('cod')
Recipe Load (0.9ms) SELECT DISTINCT "recipes".* FROM "recipes" INNER JOIN "ingredients" ON "ingredients"."recipe_id" = "recipes"."id" WHERE (lower(ingredients.name) LIKE '%cod%' OR lower(recipes.name) LIKE '%cod%')
=>
[#<Recipe:0x0000000114812300
id: 227,
name: "Fish Tacos",
steps:
"<div>To make beer batter: In a large bowl, combine flour, cornstarch, baking powder, and salt. Blend egg and beer, then quickly stir into the flour mixture (don't worry about a few lumps).</div><div><br>To make white sauce: In a medium bowl, mix together yogurt and mayonnaise. Gradually stir in fresh lime juice until consistency is slightly runny. Season with jalapeno, capers, oregano, cumin, dill, and cayenne.</div><div><br>Heat oil in deep-fryer to 375 degrees F (190 degrees C).</div><div><br>Dust fish pieces lightly with flour. Dip into beer batter, and fry until crisp and golden brown. Drain on paper towels. Lightly fry tortillas; not too crisp. To serve, place fried fish in a tortilla, and top with shredded cabbage, and white sauce.</div>",
desc: nil,
created_at: Sat, 24 Dec 2022 16:03:44.122092000 UTC +00:00,
updated_at: Sat, 24 Dec 2022 16:05:53.886182000 UTC +00:00>]
的SQLSELECT DISTINCT "recipes".* FROM "recipes" INNER JOIN "ingredients" ON "ingredients"."recipe_id" = "recipes"."id" WHERE (lower(ingredients.name) LIKE '%cod%' OR lower(recipes.name) LIKE '%cod%')
我怎么能做相反的事呢?如果我想搜索任何配方不包含奶酪,牛肉等,我如何改变ActiveRecord连接,而不是每个关联的记录。
换句话说,我如何更改查询以返回Recipes
,其中没有成分具有与查询q
匹配的名称?
使用当前的方法,我一直在尝试返回每个Recipe
,因为每个配方至少有一种成分与查询不匹配。
Recipe.joins(:ingredients).where('ingredients.name NOT LIKE ?', 'cheese')
提前感谢!
Recipe.where(
Ingredient.where('ingredients.name LIKE %?%', 'cheese')
.where(Ingredient.arel_table[:recipe_id].eq(Recipe.arel_table[:id]))
.arel
.exist
.not
)