尝试在对象上使用“build_association”方法时,我的控制器中出现“NoMethodError”? Rails 4

时间:2015-04-03 22:06:48

标签: ruby-on-rails ruby-on-rails-4 activerecord associations

所以我有三个表:位置,项目和成分,彼此之间具有以下关系:

  • Location有很多Items
  • Item属于Location且有许多Ingredients
  • Ingredient属于Item

在查看项目时(在show.html.haml中),我希望能够在页面上添加它包含的成分,同时使用AJAX remote: true作为表单。但是,一旦我进入create的{​​{1}}操作,我无法执行此操作:

IngredientsController

点是,控制器不断向@ingredient = item.build_ingredient(:name => ingredient_params[:name], etc..) NoMethodErrorbuild_ingredient投掷create_ingredient等等。没有任何作用。但createLocation之间的关系完全正常。

但对我来说奇怪的是,这是有效的:

Items

我对Rails还有点新意,我每天都在练习。通常情况下,我最终会通过谷歌在网上找到一个解决方案,但这个让我特别难过,在阅读Rails documentation关联后,我仍然没有遇到任何直接解决某种问题的问题。层状"模型之间的关联。

所以这就是我所拥有的:

成分控制器

@ingredient = Ingredient.new
@ingredient.build_item(hashes for an Item object here, etc..)

show.html.haml(Items)

class IngredientsController < ApplicationController
  def create

    # This works
    location = Location.find_by(:location_id => ingredient_params[:id])

    # This also works
    item = location.items.where(:item_id => ingredient_params[:menu_item_id])

    # This does not work
    @ingredient = item.build_ingredient(:name => ingredient_params[:name], :unit => ingredient_params[:unit], :value => ingredient_params[:value])

    respond_to do |format|
      format.js { render nothing: true }
    end
  end

  private def ingredient_params
    params.require(:ingredient).permit(:id, :menu_item_id, :name, :unit, :value)
  end
end

位置模型

.panel.panel-default
  = form_for @ingredient, remote: true do |f|
    .panel-heading
      New Ingredient
    .panel-body
      = f.hidden_field :id, :value => params[:id]
      = f.hidden_field :menu_item_id, :value => params[:menu_item_id]
      = f.select :name, options_from_collection_for_select(Supplylist.all, "id", "item"), { :prompt => "Select..." }, :class => "form-control ingredient-select"
      %br
      = f.text_field :value, :class => "form-control"
      %br
      = f.select :unit, options_from_collection_for_select(UnitType.all, "id", "name"), { :prompt => "Select..." }, :class => "form-control ingredient-select"
    .panel-footer
      = f.submit "Add", :class => "btn btn-success"

项目模型

class Location < ActiveRecord::Base
  has_many :items

  @url

  def getResponse
      response = RestClient.get(
        @url,
        {:content_type => :json, :'Api-Key' => '000000000000000000000'})

      return response
  end

  def setURL(url)
      @url = url
  end

  def getJSON
      return getResponse()
  end

  def getData(url)
      self.setURL(url)
      return JSON.parse(getJSON())
  end
end

成分模型

class Item < ActiveRecord::Base
  belongs_to :location
  has_many :ingredients
end

另外,请注意:

  • 我的数据库中的class Ingredient < ActiveRecord::Base belongs_to :item end 表有一个items外键列。
  • 我的数据库中的location_id表有一个ingredients外键列。

这两个列都是在使用item_idlocation:belongs_to创建模型时创建的。

1 个答案:

答案 0 :(得分:1)

首先,item不包含单个项目。将您的商品查询更改为:

item = location.items.where(:item_id => ingredient_params[:menu_item_id]).first

然后你可以使用:

item.ingredients.build(:name => ingredient_params[:name], etc..)

build_<association_name>仅对belongs_to或has_one关联有效。