[英]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
我的代码如下
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
class Ingredient < ActiveRecord::Base
attr_protected :id, :recipe_id
belongs_to :recipe
validates_presence_of :name
#validates_presence_of :recipe
end
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
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. 我将根据要求提供意见,但正如我之前所说,我认为它不是那么高级。
attr_accessible
for Recipe
model and add there :ingredients_attributes
Recipe
模型设置attr_accessible
并在其中添加:ingredients_attributes
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.