我在尝试匹配我正在开发的应用程序中的多态关联时遇到问题,在用户和食谱的膳食要求之间。在控制台中,我可以使用它 - 如果我将具有等于'[2]'的diet_requirement_ids的用户与具有相同孩子的食谱匹配,则可以正常工作。
然而,当我运行应用程序时,尽管调用了相同的用户和配方,但是将两个评估的方法比较为“false”。
希望很清楚,这里有一些代码可以解释这个:
在控制台中
one = User.first
two = Recipe.first
one.dietary_requirement_ids.any? && ((one.dietary_requirement_ids & two.dietary_requirement_ids) == one.dietary_requirement_ids)
# returns true, as it should
但是,在视图中......
我使用视图可访问的辅助方法,如下所示:
def dietary_requirement_matcher(one, two)
one.dietary_requirement_ids.any? && ((one.dietary_requirement_ids & two.dietary_requirement_ids) == one.dietary_requirement_ids)
end
因此:
<% Recipe.all.each do |recipe| %>
<li><%= dietary_requirement_matcher(@user, recipe) %></li>
<% end %>
<!-- which all return false, including those that shouldn't! -->
我不知道为什么它会在控制台中返回正确的结果而不是视图。我已经尝试了几件事来调试它,如下所示:
将辅助方法更改为以下方法可以正确评估配方(即为用户提供正确的diet_requirement_ids):
def dietary_requirement_matcher(one, two)
([1, 2] & two.dietary_requirement_ids) == [1, 2]
end
@user.inspect
拉出正确的用户。但是,@user.dietary_requirement_ids.inspect
会拉出一个空数组(尽管仍在控制台中工作)。
我已经检查过用户,并且食谱都已在控制台中正确保存。
这里有一些额外的代码,可以很方便地解决这个问题:
模型
配方
has_many :dietary_requirements, as: :classifiable
用户
has_many :dietary_requirements, as: :classifiable
饮食要求
belongs_to :classifiable, polymorphic: true
控制器
@recipes = Recipe.all
@user = current_user #auth method - debug shows this picking up the correct user in the view, albeit not their dietary requirements
查看(不完整,我在修复时进行调试)
<ul>
<% Recipe.all.each do |recipe| %>
<li><%= recipe.name %> = <%= dietary_requirement_matcher(@user, recipe) %></li>
<% end %>
</ul>
<p><%= dietary_requirement_matcher(@user, Recipe.first) %></p> <!-- returns false, when I'm after true -->
<p><%= @user.dietary_requirements.inspect %></p> <!-- returns '#<ActiveRecord::Associations::CollectionProxy []>' -->
我认为对此的修复可能真的简单,我只是没有发现这个,因为我是一个无知的新手。如果有人可以提供帮助,我会非常感激!史蒂夫。
修改
进行更多挖掘,我有一种感觉,这可能是应用程序在数据库中查找信息的方式的问题。我正在运行类似的逻辑与用户(通过冰箱)和食谱成分(有效!)的多次通过关系,日志显示访问这两个信息的不同路径。
我认为,因为多态关系在搜索数据库时会查找classifiable_id和(至关重要的)classifiable_type,这里可分类的类型变得混杂起来。我有一种感觉,SQLite正在寻找用户的膳食要求,但使用的是'Recipe'而不是'User'的classifiable_type。
任何人都能在这里阐明我的想法吗?那里有什么感觉还是狂人的狂言?这是页面加载时的日志:
Started GET "/fridges/meals" for 151.229.93.203 at 2015-02-17 16:26:42 +0000
Processing by FridgesController#meals as HTML
#code for matching User Ingredients to Recipe Ingredients
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
(0.3ms) SELECT COUNT(*) FROM "recipes"
Recipe Load (0.3ms) SELECT "recipes".* FROM "recipes"
Ingredient Exists (0.2ms) SELECT 1 AS one FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? LIMIT 1 [["recipe_id", 1]]
Fridge Load (0.2ms) SELECT "fridges".* FROM "fridges" WHERE "fridges"."user_id" = ? LIMIT 1 [["user_id", 2]]
(0.2ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "fridge_ingredients" ON "ingredients"."id" = "fridge_ingredients"."ingredient_id" WHERE "fridge_ingredients"."fridge_id" = ? [["fridge_id", 5]]
(0.2ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? [["recipe_id", 1]]
CACHE (0.0ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? [["recipe_id", 1]]
(0.2ms) SELECT "dietary_requirements".id FROM "dietary_requirements" WHERE "dietary_requirements"."classifiable_id" = ? AND "dietary_requirements"."classifiable_type" = ? [["classifiable_id", 2], ["classifiable_type", "User"]]
Ingredient Load (0.2ms) SELECT "ingredients".* FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? [["recipe_id", 1]]
Ingredient Exists (0.1ms) SELECT 1 AS one FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? LIMIT 1 [["recipe_id", 2]]
CACHE (0.0ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "fridge_ingredients" ON "ingredients"."id" = "fridge_ingredients"."ingredient_id" WHERE "fridge_ingredients"."fridge_id" = ? [["fridge_id", 5]]
(0.1ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? [["recipe_id", 2]]
CACHE (0.0ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? [["recipe_id", 2]]
Ingredient Exists (0.1ms) SELECT 1 AS one FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? LIMIT 1 [["recipe_id", 3]]
Ingredient Exists (0.1ms) SELECT 1 AS one FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? LIMIT 1 [["recipe_id", 4]]
Rendered shared/_matcher.html.erb (21.3ms)
CACHE (0.0ms) SELECT "recipes".* FROM "recipes"
CACHE (0.0ms) SELECT 1 AS one FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? LIMIT 1 [["recipe_id", 1]]
CACHE (0.0ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "fridge_ingredients" ON "ingredients"."id" = "fridge_ingredients"."ingredient_id" WHERE "fridge_ingredients"."fridge_id" = ? [["fridge_id", 5]]
CACHE (0.0ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? [["recipe_id", 1]]
CACHE (0.0ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? [["recipe_id", 1]]
CACHE (0.0ms) SELECT 1 AS one FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? LIMIT 1 [["recipe_id", 2]]
CACHE (0.0ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "fridge_ingredients" ON "ingredients"."id" = "fridge_ingredients"."ingredient_id" WHERE "fridge_ingredients"."fridge_id" = ? [["fridge_id", 5]]
CACHE (0.0ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? [["recipe_id", 2]]
CACHE (0.0ms) SELECT "ingredients".id FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? [["recipe_id", 2]]
CACHE (0.0ms) SELECT 1 AS one FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? LIMIT 1 [["recipe_id", 3]]
CACHE (0.0ms) SELECT 1 AS one FROM "ingredients" INNER JOIN "recipe_ingredients" ON "ingredients"."id" = "recipe_ingredients"."ingredient_id" WHERE "recipe_ingredients"."recipe_id" = ? LIMIT 1 [["recipe_id", 4]]
#code for matching the User and Recipe Dietary Requirements
CACHE (0.0ms) SELECT "recipes".* FROM "recipes"
CACHE (0.0ms) SELECT "dietary_requirements".id FROM "dietary_requirements" WHERE "dietary_requirements"."classifiable_id" = ? AND "dietary_requirements"."classifiable_type" = ? [["classifiable_id", 2], ["classifiable_type", "User"]]
CACHE (0.0ms) SELECT "dietary_requirements".id FROM "dietary_requirements" WHERE "dietary_requirements"."classifiable_id" = ? AND "dietary_requirements"."classifiable_type" = ? [["classifiable_id", 2], ["classifiable_type", "User"]]
CACHE (0.0ms) SELECT "dietary_requirements".id FROM "dietary_requirements" WHERE "dietary_requirements"."classifiable_id" = ? AND "dietary_requirements"."classifiable_type" = ? [["classifiable_id", 2], ["classifiable_type", "User"]]
CACHE (0.0ms) SELECT "dietary_requirements".id FROM "dietary_requirements" WHERE "dietary_requirements"."classifiable_id" = ? AND "dietary_requirements"."classifiable_type" = ? [["classifiable_id", 2], ["classifiable_type", "User"]]
Recipe Load (0.4ms) SELECT "recipes".* FROM "recipes" ORDER BY "recipes"."id" ASC LIMIT 1
CACHE (0.0ms) SELECT "dietary_requirements".id FROM "dietary_requirements" WHERE "dietary_requirements"."classifiable_id" = ? AND "dietary_requirements"."classifiable_type" = ? [["classifiable_id", 2], ["classifiable_type", "User"]]
DietaryRequirement Load (0.2ms) SELECT "dietary_requirements".* FROM "dietary_requirements" WHERE "dietary_requirements"."classifiable_id" = ? AND "dietary_requirements"."classifiable_type" = ? [["classifiable_id", 2], ["classifiable_type", "User"]]
Rendered fridges/meals.html.erb within layouts/application (42.3ms)
Cuisine Load (0.3ms) SELECT "cuisines".* FROM "cuisines"
Category Load (0.2ms) SELECT "categories".* FROM "categories"
Rendered shared/_header.html.erb (3.3ms)
Completed 200 OK in 593ms (Views: 579.3ms | ActiveRecord: 4.2ms)
答案 0 :(得分:1)
我在想,这可能是您的多态关联设置的方式:膳食要求可以属于User
或Recipe
,因为您使用的是:classifiable
参考列双方。我遇到了类似的问题,我的解决方案是将两个单独的引用列添加到多态类中,如下所示:
DietaryRequirement belongs to :owner, polymorphic: true
,belongs to :processor, polymorphic: true
。然后将以下列添加到Dietary_Requirements
表:owner_id, owner_type, processor_id, processor_type
。
<强>配方即可。 has_many :dietary_requirements, as: :processor
has_many :dietary_requirements, as: :owner