简体   繁体   English

accepts_nested_attributes_for不保存嵌套属性

[英]accepts_nested_attributes_for not saving nested attributes

I've been stuck on this one problem for days now. 我已经被这个问题困扰了好几天了。 This is my first Rails app, and I'm almost finished, only to be slowed considerably by this. 这是我的第一个Rails应用程序,我快要完成了,但是为此感到相当慢。

I read that using accepts_nested_attributes_for is the best solution to my problem of nesting Ingredients within a Recipe for use with forms, but so far I have had no luck. 我读到,使用accepts_nested_attributes_for是解决在配方中嵌套配料以与表格一起使用的问题的最佳解决方案,但是到目前为止,我还没有运气。 I have read everything I can find on the subject. 我已经阅读了有关该主题的所有文章。 The API says the model now has a (in my case) ingredients_attributes= method, which I do not yet see. API说,该模型现在有一个(就我而言)的Ingredients_attributes =方法,我还没有看到。 I have attempted using update_attributes in the console with the hash 我试图在控制台中使用带有哈希值的update_attributes

recipe.update_attrubutes {:ingredients_attributes=>[{:name=>"Test Ingredient"}]}

This comes back true , but shows no changes in the recipe object. 这返回true ,但是在配方对象中未显示任何更改。

I have attempted many approaches, my first being just using fields_for inside of a forms_for inside of my View. 我尝试了许多方法,我的第一个方法是在View内部的forms_for内部使用fields_for。 Since this wasn't working and I was testing the code to no avail, I started looking deeper and the problem definitely goes deeper than the View. 由于这不起作用,并且我没有对代码进行测试,因此我开始更深入地研究,问题肯定比View更加深入。

Any help would be much appreciated. 任何帮助将非常感激。 My code follows 我的代码如下

Recipe Model 配方模型

Sorry about the confusing conversions between the db-styled names and the display-styled names. 抱歉,数据库样式名称和显示样式名称之间的转换令人困惑。 This is my best fix so far to maintain the both of them. 到目前为止,这是保持两者的最佳解决方案。

class Recipe < ActiveRecord::Base

  DISH_TYPES={""=>"", "Breakfast"=>"breakfast", "Lunch"=>"lunch", "Soup"=>"soup", "Entree"=>"entree", "Desert"=>"desert"}
  SEASONS={"Any Season"=>"any", "Fall"=>"fall", "Winter"=>"winter", "Spring"=>"spring", "Summer"=>"summer"}
  DIETS={""=>"", "Vegan"=>"vegan", "Vegetarian"=>"vegetarian", "Omnivore"=>"omnivore"}

  DISH_TYPES_R={""=>"", "breakfast"=>"Breakfast", "lunch"=>"Lunch", "soup"=>"Soup", "entree"=>"Entree", "desert"=>"Desert"}
  SEASONS_R={"any"=>"Any Season", "fall"=>"Fall", "winter"=>"Winter", "spring"=>"Spring", "summer"=>"Summer"}
  DIETS_R={""=>"", "vegan"=>"Vegan", "vegetarian"=>"Vegetarian", "omnivore"=>"Omnivore"}

  attr_protected :user_id
  # Do NOT include user_id in the attr_accessible method, to avoid
  # the possibility of it being changed externally.
  belongs_to :user
  validates_presence_of :user  
  has_many :ingredients, dependent: :destroy # , inverse_of: :recipe

  # Allows for forms to write attributes down the hierarchy.
  accepts_nested_attributes_for :ingredients, allow_destroy: true , reject_if: lambda { |a| a[:content].blank? }

  before_save do
    # Lowercase and convert to strings all of the attributes
    # that require a specific format, namely the values in the
    # constant hashes above.
    STRING_ATTRIBUTES.each do |s|
      self.send("#{s}=".to_sym, self.send(s).downcase.to_s)
    end
  end

  validates :user_id, presence: true
  validates :name,  presence: true,
                    length: { maximum: 64 } #,uniqueness: true
  validates :dish_type, inclusion: { in: DISH_TYPES.values }
  validates :season, inclusion: { in: SEASONS.values }
  validates :diet, inclusion: { in: DIETS.values}
  validates :directions,  presence: true,
                          length: { maximum: 8192 }

  validates_associated :ingredients


  default_scope order: "recipes.created_at DESC"


  def method_missing (method)
    method = method.to_s
    if method.slice!("display_")
      if STRING_ATTRIBUTES.include?(method.to_sym)
        hash_name = method.upcase + 'S_R'
        Recipe.const_get(hash_name)[self.send(method.to_sym)]
      else
        method
      end
    else 
      method.class
    end
  end

  private

    STRING_ATTRIBUTES = [:dish_type, :season, :diet]

end

Ingredient Model 成分模型

class Ingredient < ActiveRecord::Base

  attr_protected :id, :recipe_id
  belongs_to :recipe

  validates_presence_of :name
  #validates_presence_of :recipe
end

Recipe Controller 配方控制器

I've read that I shouldn't have to change anything in the controller. 我读到我不必在控制器中进行任何更改。 I have only added one line, so that the Ingredient form shows up in my view 我只添加了一行,以便在我的视图中显示成分表

class RecipesController < ApplicationController
  before_filter :signed_in_user, only: [:create, :edit, :destroy]

  def index
    @recipes = Recipe.all
  end

  def new
    if signed_in?
      @recipe = current_user.recipes.build 
      @recipe.ingredients.build
    else
      flash[:error] = "First you have to register! Sign up here and start adding recipes ASAP."
      redirect_to signup_path
    end
  end

  def create
    @new_recipe = current_user.recipes.build(params[:recipe])
    if @new_recipe.save
      flash[:success] = "You've successfully added #{@new_recipe.name}!"
      redirect_to @new_recipe
    else
      redirect_to 'new'
    end
  end

  def edit
    @recipe = Recipe.find(params[:id])
  end

  def show
    @recipe = Recipe.find(params[:id].to_i)
  end

end

Ingredients Controller 配料控制器

I don't believe there is any use for an Ingredient Controller, since the ingredients (for now) will only be accessed through their parent Recipe. 我不相信成分控制器有什么用,因为成分(目前)只能通过其父配方来访问。

I will include the views upon request, but as I stated earlier, I don't believe it is that high-level. 我将根据要求提供意见,但正如我之前所说,我认为它不是那么高级。

  1. You need to set attr_accessible for Recipe model and add there :ingredients_attributes 您需要为Recipe模型设置attr_accessible并在其中添加:ingredients_attributes
  2. As i see in your config, you have reject_if: lambda { |a| a[:content].blank? } 正如我在您的配置中看到的那样,您有reject_if: lambda { |a| a[:content].blank? } reject_if: lambda { |a| a[:content].blank? } reject_if: lambda { |a| a[:content].blank? } for ingrediens_attributes and you are setting it only with name reject_if: lambda { |a| a[:content].blank? } for ingrediens_attributes,而您仅使用名称进行设置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM