Rails 多态关联显示在控制台中但不在视图中

Rails polymorphic association showing in console but not in view

我在尝试匹配我正在开发的应用程序中用户和食谱的饮食要求之间的多态关联时遇到问题。在控制台中,我可以让它工作 - 如果我将 dietary_requirement_ids 等于 '[2]' 的用户匹配到具有相同 children 的食谱,它就可以工作。

但是,当我 运行 应用程序时,尽管调用了相同的用户和食谱,但比较两者的方法评估为 '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! -->

我不知道为什么它会 return 在控制台而不是视图中得到正确的结果。我尝试了一些方法来调试它,如下所示:

将辅助方法更改为以下方法可以正确评估食谱(即将用户替换为正确的 dietary_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 []>' -->

我认为这个问题的修复可能真的简单,我只是没有发现这个问题,因为我是一个无知的新手。如果有人可以提供帮助,我将非常感激!史蒂夫


编辑

进一步挖掘,我觉得这可能是应用程序在数据库中查找信息的方式存在问题。我正在 运行 与 has-many-through 用户(通过 Fridge)和配方成分(有效!)的关系建立类似的逻辑,并且日志显示了访问这两条信息的不同路径。

认为,因为多态关系在搜索数据库时寻找classifiable_id和(至关重要的)classifiable_type,可分类类型正在获取混在这里。我感觉 SQLite 正在寻找用户的饮食要求,但是 classifiable_type 是 'Recipe' 而不是 'User'.

有谁能阐明我的想法吗?那里有任何意义或疯子的胡言乱语吗?这是页面加载时的日志:

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)

我在想,这可能是您的多态关联的设置方式:饮食需求可以属于 User,也可以属于 Recipe,因为您正在使用 :classifiable两者的参考列。我遇到过类似的问题,我的解决方案是向多态 class 添加两个单独的引用列,如下所示:

  • 饮食要求 belongs to :owner, polymorphic: true, belongs to :processor, polymorphic: true。然后将以下列添加到 Dietary_Requirements table:owner_id, owner_type, processor_id, processor_type.

  • 食谱has_many :dietary_requirements, as: :processor

  • 用户has_many :dietary_requirements, as: :owner