Rails 茧 gem 不工作
Rails Cocoon gem not working
尝试使用 Cocoon gem 为食谱应用程序创建嵌套表单,但不允许我保存新食谱,尽管我已经添加了配料名称和食谱步骤。
我的本地主机中不断出现以下错误:
2 Prevented this recipe from saving
- Ingredients recipe must exist
- Directions recipe must exist
我遵循了一个教程,阅读了 Cocoon 文档并在 Google 和 SO 上研究了这个问题,但仍然找不到。几天来我一直在努力解决这个问题。非常感谢您的帮助。
型号
class Recipe < ActiveRecord::Base
belongs_to :user
has_many :ingredients
has_many :directions
accepts_nested_attributes_for :ingredients,
reject_if: proc { |attributes| attributes['name'].blank? },
allow_destroy: true
accepts_nested_attributes_for :directions,
reject_if: proc { |attributes| attributes['step'].blank? },
allow_destroy: true
validates :title, :description, :image, presence: true
has_attached_file :image, styles: { :medium => "400x400#" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
views/recipes/_form
<%= simple_form_for @recipe do |f| %>
<% if @recipe.errors.any? %>
<div id="error">
<p><%= @recipe.errors.count %> Prevented this recipe from saving</p>
<ul>
<% @recipe.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="panel-body">
<%= f.input :title %>
<%= f.input :description %>
<%= f.input :image %>
</div>
<div class="row">
<div class="col-md-6">
<h3>Ingredients</h3>
<div id="ingredients">
<%= f.simple_fields_for :ingredients do |ingredient| %>
<%= render 'ingredient_fields', f: ingredient %>
<% end %>
<div class="links">
<%= link_to_add_association 'Add Ingredient', f, :ingredients, partial: 'ingredient_fields', class: "btn btn-default add-button" %>
</div>
</div>
</div>
<div class="col-md-6">
<h3>Directions</h3>
<div id="directions">
<%= f.simple_fields_for :directions do |direction| %>
<%= render 'direction_fields', f: direction %>
<% end %>
<div class="links">
<%= link_to_add_association 'Add Step', f, :directions, partial: 'direction_fields', class: "btn btn-default add-button" %>
</div>
</div>
</div>
</div>
<div>
<%= f.button :submit, class: "btn btn-primary" %>
</div>
views/recipes/_ingredient_fields
<div class="form-inline clearfix">
<div class="nested-fields">
<%= f.input :name, class: "form-control" %>
<%= link_to_remove_association 'Remove', f, class: "btn btn-default" %>
</div>
</div>
views/recipes/_direction_fields
<div class="form-inline clearfix">
<div class="nested-fields">
<%= f.input :step, class: "form-control" %>
<%= link_to_remove_association 'Remove Step', f, class: "btn btn-default" %>
</div>
</div>
控制器
class RecipesController < ApplicationController
before_action :find_recipe, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
@recipe = Recipe.all.order("created_at DESC")
end
def show
end
def new
@recipe = current_user.recipes.build
end
def create
@recipe = current_user.recipes.build(recipe_params)
if @recipe.save
redirect_to @recipe, notice: "Successfully created new recipe"
else
render 'new'
end
end
def edit
end
def update
if @recipe.update(recipe_params)
redirect_to @recipe
else
render 'edit'
end
end
def destroy
@recipe.destroy
redirect_to root_path, notice: "Successfully deleted recipe"
end
private
def recipe_params
params.require(:recipe).permit(:title, :description, :image, ingredients_attributes: [:id, :name, :_destroy], directions_attributes: [:id, :step, :_destroy])
end
def find_recipe
@recipe = Recipe.find(params[:id])
end
end
如果它有助于调试,这里是存储库的 link:https://github.com/rchrdchn/rails-projects/tree/master/recipe_box
当您创建新食谱时,您没有食谱对象,因为它在服务器内存中。但是当你更新它时,配方对象会被保留。
这就是为什么您会收到配料配方必须存在和说明配方必须存在错误的原因。
要解决这个问题,您必须在关联中添加 inverse_of。
class Recipe
has_many :ingredients, inverse_of: :recipe
has_many :directions, inverse_of: :recipe
class Ingredient
belongs_to :recipe, inverse_of: :ingredients
class Direction
belongs_to :recipe, inverse_of: :directions
尝试使用 Cocoon gem 为食谱应用程序创建嵌套表单,但不允许我保存新食谱,尽管我已经添加了配料名称和食谱步骤。
我的本地主机中不断出现以下错误:
2 Prevented this recipe from saving
- Ingredients recipe must exist
- Directions recipe must exist
我遵循了一个教程,阅读了 Cocoon 文档并在 Google 和 SO 上研究了这个问题,但仍然找不到。几天来我一直在努力解决这个问题。非常感谢您的帮助。
型号
class Recipe < ActiveRecord::Base
belongs_to :user
has_many :ingredients
has_many :directions
accepts_nested_attributes_for :ingredients,
reject_if: proc { |attributes| attributes['name'].blank? },
allow_destroy: true
accepts_nested_attributes_for :directions,
reject_if: proc { |attributes| attributes['step'].blank? },
allow_destroy: true
validates :title, :description, :image, presence: true
has_attached_file :image, styles: { :medium => "400x400#" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
views/recipes/_form
<%= simple_form_for @recipe do |f| %>
<% if @recipe.errors.any? %>
<div id="error">
<p><%= @recipe.errors.count %> Prevented this recipe from saving</p>
<ul>
<% @recipe.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="panel-body">
<%= f.input :title %>
<%= f.input :description %>
<%= f.input :image %>
</div>
<div class="row">
<div class="col-md-6">
<h3>Ingredients</h3>
<div id="ingredients">
<%= f.simple_fields_for :ingredients do |ingredient| %>
<%= render 'ingredient_fields', f: ingredient %>
<% end %>
<div class="links">
<%= link_to_add_association 'Add Ingredient', f, :ingredients, partial: 'ingredient_fields', class: "btn btn-default add-button" %>
</div>
</div>
</div>
<div class="col-md-6">
<h3>Directions</h3>
<div id="directions">
<%= f.simple_fields_for :directions do |direction| %>
<%= render 'direction_fields', f: direction %>
<% end %>
<div class="links">
<%= link_to_add_association 'Add Step', f, :directions, partial: 'direction_fields', class: "btn btn-default add-button" %>
</div>
</div>
</div>
</div>
<div>
<%= f.button :submit, class: "btn btn-primary" %>
</div>
views/recipes/_ingredient_fields
<div class="form-inline clearfix">
<div class="nested-fields">
<%= f.input :name, class: "form-control" %>
<%= link_to_remove_association 'Remove', f, class: "btn btn-default" %>
</div>
</div>
views/recipes/_direction_fields
<div class="form-inline clearfix">
<div class="nested-fields">
<%= f.input :step, class: "form-control" %>
<%= link_to_remove_association 'Remove Step', f, class: "btn btn-default" %>
</div>
</div>
控制器
class RecipesController < ApplicationController
before_action :find_recipe, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
@recipe = Recipe.all.order("created_at DESC")
end
def show
end
def new
@recipe = current_user.recipes.build
end
def create
@recipe = current_user.recipes.build(recipe_params)
if @recipe.save
redirect_to @recipe, notice: "Successfully created new recipe"
else
render 'new'
end
end
def edit
end
def update
if @recipe.update(recipe_params)
redirect_to @recipe
else
render 'edit'
end
end
def destroy
@recipe.destroy
redirect_to root_path, notice: "Successfully deleted recipe"
end
private
def recipe_params
params.require(:recipe).permit(:title, :description, :image, ingredients_attributes: [:id, :name, :_destroy], directions_attributes: [:id, :step, :_destroy])
end
def find_recipe
@recipe = Recipe.find(params[:id])
end
end
如果它有助于调试,这里是存储库的 link:https://github.com/rchrdchn/rails-projects/tree/master/recipe_box
当您创建新食谱时,您没有食谱对象,因为它在服务器内存中。但是当你更新它时,配方对象会被保留。
这就是为什么您会收到配料配方必须存在和说明配方必须存在错误的原因。
要解决这个问题,您必须在关联中添加 inverse_of。
class Recipe
has_many :ingredients, inverse_of: :recipe
has_many :directions, inverse_of: :recipe
class Ingredient
belongs_to :recipe, inverse_of: :ingredients
class Direction
belongs_to :recipe, inverse_of: :directions