无法从关联的模型导轨访问属性

时间:2018-12-24 14:44:14

标签: ruby-on-rails database

我有三种模型,成分,配方成分和配方

class Ingredient < ApplicationRecord
  has_many :recipe_ingredients
end

class RecipeIngredient < ApplicationRecord
 belongs_to :recipy, :dependent => :destroy
 belongs_to :ingredient
end

class Recipy < ApplicationRecord
  has_many :recipy_steps
 has_many :recipe_ingredients, :dependent => :delete_all
end

我正在尝试从食谱显示页面访问配料表中的ing_name属性。

<% @recipe_ingredients.each do |ing| %>
<p> <%= ing.amount  %> <%= ing.unit %>
<%= ing.ingredient.ing_name %>
</p>

def从收据控制器显示:

def show
 @recipe_ingredients = @recipy.recipe_ingredients
end

但是我仍然收到以下错误消息: nil:NilClass的未定义方法“ ing_name”

我的Ingredient_params:

def ingredient_params
params.require(:ingredient).permit(:ing_name)
end

它的确像这样工作:

    <%= Ingredient.where(id: ing.ingredient_id).pluck(:ing_name) %>

但是,如果我理解正确,这不会使用表之间的连接吗?有什么帮助吗?谢谢。

2 个答案:

答案 0 :(得分:0)

您有成分nil,这就是导致错误的原因。

必须是您的控制器具有一些before_action钩子才能加载配方

class RecipesController < ApplicationController
  before_action :load_recipy, only: :show

  def show
    @recipe_ingredients = @recipy.recipe_ingredients
  end

 private
 def load_recipy
   @recipy = Recipy.find(params[:id])
  end
end

您可以try以避免出现零错误(undefined method 'ing_name' for nil:NilClass

<% @recipe_ingredients.each do |ing| %>
<p> <%= ing.amount  %> <%= ing.unit %>
<%= ing.try(:ingredient).try(:ing_name) %>
</p>

默认情况下,从Rails 5中有一个required选项可以使配料始终不是nullable

如下所示

belongs_to :ingredient, required: true

这还将防止此错误

class RecipeIngredient < ApplicationRecord
 belongs_to :recipy, :dependent => :destroy
 belongs_to :ingredient, required: true
end

答案 1 :(得分:0)

问题是因为在您的show方法@recipy中为零, 这通常是显示代码

控制器

def show
  @recipy = Recipy.find(params[:id]) # --> you missed this line
  @recipe_ingredients = @recipy.recipe_ingredients # @recipy will be null without line above
end

视图

<% @recipe_ingredients.each do |ing| %>
  <p> <%= ing.amount  %> <%= ing.unit %> <%= ing.ingredient.ing_name %> </p>
<% end %>

我还要向您的模型关系添加一些建议,因为成分和配方显示出多对多的关系

class Ingredient < ApplicationRecord
  # -> recipe_ingredients -> recipies
  has_many :recipe_ingredients, :dependent => :destroy
  has_many :recipies, through: :recipe_ingredients
end

class RecipeIngredient < ApplicationRecord
 belongs_to :recipy
 belongs_to :ingredient
end

class Recipy < ApplicationRecord
  has_many :recipy_steps
  # -> recipe_ingredients -> ingredients
  has_many :recipe_ingredients, :dependent => :destroy
  has_many :ingredients, through: :recipe_ingredients
end