如何将has_many:通过细节添加到表单RoR

时间:2011-10-26 22:00:15

标签: ruby-on-rails ruby has-many

我正在为Ruby on Rails(配方应用程序)做一个常见的学习应用程序。具体来说,作为一个has_many:通过关系处理食谱和配料。通过查看一百万个示例和问题,我得到了多对多的关系设置和我的多模型表单,但是我想添加一个额外的字段并且无法使其正常工作。感觉就像我接近理解这些东西是如何工作的。以下是快速详细信息:

型号:

class Ingredient < ActiveRecord::Base
  has_many :recipe_ingredients
  has_many :recipes, :through => :recipe_ingredients
end

class RecipeIngredient < ActiveRecord::Base
  belongs_to :recipe
  belongs_to :ingredient
end

class Recipe < ActiveRecord::Base
  has_many :recipe_ingredients
  has_many :ingredients, :through => :recipe_ingredients
  accepts_nested_attributes_for :ingredients, :recipe_ingredients

  def new_recipe_ingredient_attributes=(recipe_ingredient_attributes)
    recipe_ingredient_attributes.each do |attributes|
      recipe_ingredients.build(attributes)
    end
  end

  def existing_recipe_ingredient_attributes=(recipe_ingredient_attributes)
    recipe_ingredients.reject(&:new_record?).each do |recipe_ingredient|
      attributes = recipe_ingredient_attributes[recipe_ingredient.id.to_s]
      if attributes
        recipe_ingredient.attributes = attributes
      else
        recipe_ingredient.delete(recipe_ingredient)
      end
    end
  end

  def save_recipe_ingredients
    recipe_ingredients.each do |recipe_ingredient|
      recipe_ingredient.save(false)
    end
  end
end

控制器:

def create
   @recipe = Recipe.new(params[:recipe])
   if @recipe.save
         redirect_to :action => 'show', :id => @recipe
         flash[:notice] = "Your record has been saved."
   else
         render :action => 'new'
   end
end

def update
   params[:recipe][:existing_recipe_ingredient_attributes] ||= {}
   @recipe = Recipe.find(params[:id])
   if @recipe.update_attributes(params[:recipe])
      redirect_to :action => 'show', :id => @recipe
      flash[:notice] = "Your changes have been saved."
   else
      render :action => 'edit'
   end
end  

查看:

<% form_for(@recipe) do |f| %>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
etc.....
    Ingredients:
    <div id="recipe_ingredients">
      <div class="recipe_ingredient">
      <% new_or_existing = recipe_ingredient.new_record? ? 'new' : 'existing' %>
      <% prefix = "recipe[#{new_or_existing}_recipe_ingredient_attributes][]" %>
      <% fields_for prefix, recipe_ingredient do |ri_form| %>
        <p>
          <%= ri_form.collection_select(:id, Ingredient.find(:all), :id, :name, :include_blank => true) %>
          <%= ri_form.text_field :amount %>
        </p>
      <% end %>
      </div>
    </div>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

对于代码墙感到抱歉,希望它有意义。我无法理解的是为什么“金额”文本字段不起作用。我已经尝试了一百万种不同的方法,但是无法让它发挥作用。在这种情况下,我得到的错误是#“

的未定义方法`数量'

我在这里错过了什么关键联系?感谢。

1 个答案:

答案 0 :(得分:0)

乍一看,你应该简单地替换:

      <% fields_for prefix, recipe_ingredient do |ri_form| %>

使用:

      <%= fields_for prefix, recipe_ingredient do |ri_form| %>