Rails Cocoon宝石不起作用

时间:2017-12-09 06:34:44

标签: ruby-on-rails ruby nested-attributes link-to cocoon-gem

尝试使用Cocoon gem为食谱应用程序创建嵌套表单,但不允许我保存新食谱,尽管我已经添加了成分名称和配方步骤。

我在localhost中不断收到以下错误:

  

2通过保存

防止此配方      
      
  • 配料食谱必须存在
  •   
  • 方向食谱必须存在
  •   

我按照教程,阅读了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

视图/食谱/ _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>

视图/食谱/ _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>

视图/食谱/ _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

如果它有助于调试,那么这是指向存储库的链接:https://github.com/rchrdchn/rails-projects/tree/master/recipe_box

1 个答案:

答案 0 :(得分:1)

当您创建新配方时,您没有配方对象,因为它位于服务器内存中。但是当你更新它时,配方对象会被保留。

这就是为什么你必须存在配方食谱并且方向配方必须存在错误。

要解决此问题,您必须在关联中添加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