Ruby on rails 具有多态关系的所属对象不会通过嵌套形式从具有多个关系的对象中删除

Ruby on rails 具有多态关系的所属对象不会通过嵌套形式从具有多个关系的对象中删除,ruby-on-rails,ruby-on-rails-5,polymorphic-associations,cocoon-gem,Ruby On Rails,Ruby On Rails 5,Polymorphic Associations,Cocoon Gem,我试图创建一个依赖于多态关系的非常复杂的嵌套表单。我有它的大部分工作,但这一关系将不会执行删除像我期待的 配方有许多配方步骤, Recipes-teps可以是多态的,与以下三件事之一相关:技术,步骤,或配方 出于某种原因,当我试图通过嵌套表单从recipes\edit中删除recipes步骤时,rails拒绝删除recipes步骤,并将\u delete:1传递到recipes步骤。响应列在下面代码块的底部 我已尝试将与配方步骤关联的所属更改为requires:false,我已尝试添加任何可能导

我试图创建一个依赖于多态关系的非常复杂的嵌套表单。我有它的大部分工作,但这一关系将不会执行删除像我期待的

配方
有许多
配方步骤
Recipes-teps
可以是多态的,与以下三件事之一相关:
技术
步骤
,或
配方

出于某种原因,当我试图通过嵌套表单从
recipes\edit
中删除
recipes步骤时,rails拒绝删除
recipes步骤,并将
\u delete:1
传递到
recipes步骤
。响应列在下面代码块的底部

我已尝试将与
配方步骤
关联的
所属
更改为
requires:false
,我已尝试添加任何可能导致FK错误的
dependent:destroy
。我已经尝试更新
recipes\u controller.rb
Strong参数,以允许所有这些信息通过。我包括
:\u delete
:id
,以及
配方步骤所需的所有其他参数

我没有得到任何错误,只是它甚至没有尝试删除

我正在使用这些宝石:

  • 简单形式

以下是相关代码:

多态关系关注 stepable.rb 配方 recipe.rb-模型 重要信息:
“配方步骤属性”=>{“0”=>{“位置”=>“2”、“\u销毁”=>“1”、“id”=>“11”}

如您所见,
\u destroy
参数设置正确,未发送任何不允许的参数错误。但是,甚至没有尝试删除
配方步骤


我没有包含此错误的视图,因为我相信它们运行正常,这可以从传递给控制器的参数中看出。如果您认为我的
简单表单
和或
cococoon
实现可能有错误,请询问,我将添加这些代码。

问题在于de>配方
配方步骤
有两种关系:

  • 有很多:配方步骤
  • 有许多:配方步骤,如::stepable
    通过stepable.rb关注点
  • 这两个步骤都是问题所在。我将问题改为:
    有很多:通过步骤,如::stepable,类名:'RecipeStep'
    ,这解决了删除问题

    # frozen_string_literal: true
    
    # Adds the polymorphic relation to recipes through recipe_steps
    module Stepable
      extend ActiveSupport::Concern
    
      included do
        has_many :recipe_steps, as: :stepable
        has_many :recipes, through: :recipe_steps
      end
    end
    
    # frozen_string_literal: true
    # == Schema Information
    #
    # Table name: recipes
    #
    #  id          :bigint(8)        not null, primary key
    #  title       :string
    #  description :text
    #  created_at  :datetime         not null
    #  updated_at  :datetime         not null
    #
    
    # Recipe's are containers that can have as many Steps, Techniques, or even
    #   other Recipes within them.
    class Recipe < ApplicationRecord
      include Stepable
    
      has_many :recipe_steps
    
      has_many :steps,
               through: :recipe_steps,
               source: 'stepable',
               source_type: 'Step',
               dependent: :destroy
    
      has_many :techniques,
               through: :recipe_steps,
               source: 'stepable',
               source_type: 'Technique',
               dependent: :destroy
    
      has_many :recipes,
               through: :recipe_steps,
               source: 'stepable',
               source_type: 'Recipe',
               dependent: :destroy
    
      has_many :ingredients,
               through: :steps
    
      has_many :step_ingredients,
               through: :steps,
               dependent: :destroy
    
      accepts_nested_attributes_for :recipes,
                                    reject_if: :all_blank,
                                    allow_destroy: true
    
      accepts_nested_attributes_for :techniques,
                                    reject_if: :all_blank,
                                    allow_destroy: true
    
      accepts_nested_attributes_for :steps,
                                    reject_if: :all_blank,
                                    allow_destroy: true
    
      accepts_nested_attributes_for :recipe_steps,
                                    reject_if: :all_blank,
                                    allow_destroy: true
    end
    
    # frozen_string_literal: true
    
    class RecipesController < ApplicationController
      before_action :set_recipe, only: [:show, :edit, :update, :destroy]
    
      # GET /recipes
      # GET /recipes.json
      def index
        @recipes = Recipe.all.decorate
      end
    
      # GET /recipes/1
      # GET /recipes/1.json
      def show
      end
    
      # GET /recipes/new
      def new
        @recipe = Recipe.new
      end
    
      # GET /recipes/1/edit
      def edit
      end
    
      # POST /recipes
      # POST /recipes.json
      def create
        @recipe = Recipe.new(recipe_params)
    
        respond_to do |format|
          if @recipe.save
            format.html { redirect_to @recipe, notice: 'Recipe was successfully created.' }
            format.json { render :show, status: :created, location: @recipe }
          else
            format.html { render :new }
            format.json { render json: @recipe.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # PATCH/PUT /recipes/1
      # PATCH/PUT /recipes/1.json
      def update
        respond_to do |format|
          if @recipe.update(recipe_params)
            format.html { redirect_to @recipe, notice: 'Recipe was successfully updated.' }
            format.json { render :show, status: :ok, location: @recipe }
          else
            format.html { render :edit }
            format.json { render json: @recipe.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # DELETE /recipes/1
      # DELETE /recipes/1.json
      def destroy
        @recipe.destroy
        respond_to do |format|
          format.html { redirect_to recipes_url, notice: 'Recipe was successfully destroyed.' }
          format.json { head :no_content }
        end
      end
    
      private
        # Use callbacks to share common setup or constraints between actions.
        def set_recipe
          @recipe = Recipe.find(params[:id])
        end
    
        # Never trust parameters from the scary internet, only allow the white list through.
        def recipe_params
          params.require(:recipe)
                .permit(
                  :name,
                  :title,
                  :description,
                  recipe_steps_attributes: [
                    :id,
                    :position,
                    :stepable_type,
                    :stepable_id,
                    :recipe_id,
                    :_destroy
                  ],
                  recipes_attributes: [
                    :id,
                    :_destroy
                  ],
                  techniques_attributes: [
                    :id,
                    :title,
                    :description,
                    :_destroy
                  ],
                  steps_attributes: [
                    :id,
                    :title,
                    :description,
                    :_destroy,
                    step_ingredients_attributes: [
                      :id,
                      :_destroy,
                      :ingredient_id,
                      measurements_attributes: [
                        :id,
                        :unit,
                        :scalar,
                        :purpose,
                        :_destroy
                      ],
                      ingredient_attributes: [
                        :id,
                        :title,
                        :description,
                        :_destroy
                      ]
                    ]
                  ]
                )
        end
    end
    
    # frozen_string_literal: true
    
    # == Schema Information
    #
    # Table name: recipe_steps
    #
    #  id            :bigint(8)        not null, primary key
    #  recipe_id     :bigint(8)
    #  stepable_type :string
    #  stepable_id   :bigint(8)
    #  position      :integer
    #  created_at    :datetime         not null
    #  updated_at    :datetime         not null
    #
    
    # RecipeStep is the through table for relating polymorphic stepable items to
    #   the recipe.
    class RecipeStep < ApplicationRecord
      belongs_to :stepable, polymorphic: true, required: false
      belongs_to :recipe, required: false
    
      before_create :set_position
    
      accepts_nested_attributes_for :stepable,
                                    reject_if: :all_blank,
                                    allow_destroy: true
    
      default_scope -> { order(position: :asc) }
    
      private
    
      def set_position
        self.position = recipe.recipe_steps.count + 1
      end
    end
    
    Started PATCH "/recipes/3" for ::1 at 2019-02-19 15:55:20 -0500
    Processing by RecipesController#update as HTML
      Parameters: {"utf8"=>"✓", "authenticity_token"=>"21JWhw/o6ysiInTGv4gJp8pTrvh5jpscpGw2Fhm2o3OyitieRz26nBGeFaZclH21zXHBhjtF7L9ujE3yILl+IQ==", "recipe"=>{"title"=>"Pizza", "description"=>"Three eggs with cilantro, tomatoes, onions, avocados and melted Emmental cheese. With a side of roasted potatoes, and your choice of toast or croissant.", "recipe_steps_attributes"=>{"0"=>{"position"=>"2", "_destroy"=>"1", "id"=>"11"}, "1"=>{"position"=>"10", "_destroy"=>"false", "id"=>"10"}}, "steps_attributes"=>{"0"=>{"title"=>"Ricotta Stuffed Ravioli", "description"=>"Two butter croissants of your choice (plain, almond or cheese). With a side of herb butter or house-made hazelnut spread.", "step_ingredients_attributes"=>{"0"=>{"ingredient_id"=>"1", "measurements_attributes"=>{"0"=>{"unit"=>"", "scalar"=>"0.7", "_destroy"=>"false", "id"=>"15"}, "1"=>{"unit"=>"", "scalar"=>"6.7", "_destroy"=>"false", "id"=>"16"}, "2"=>{"unit"=>"", "scalar"=>"5.8", "_destroy"=>"false", "id"=>"17"}}, "_destroy"=>"false", "id"=>"11"}}, "id"=>"10"}}}, "commit"=>"Save", "id"=>"3"}
      Recipe Load (0.3ms)  SELECT  "recipes".* FROM "recipes" WHERE "recipes"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
      ↳ app/controllers/recipes_controller.rb:69
       (0.2ms)  BEGIN
      ↳ app/controllers/recipes_controller.rb:46
      RecipeStep Load (0.8ms)  SELECT "recipe_steps".* FROM "recipe_steps" WHERE "recipe_steps"."recipe_id" = $1 AND "recipe_steps"."id" IN ($2, $3) ORDER BY "recipe_steps"."position" ASC  [["recipe_id", 3], ["id", 11], ["id", 10]]
      ↳ app/controllers/recipes_controller.rb:46
      Step Load (1.0ms)  SELECT "steps".* FROM "steps" INNER JOIN "recipe_steps" ON "steps"."id" = "recipe_steps"."stepable_id" WHERE "recipe_steps"."recipe_id" = $1 AND "recipe_steps"."stepable_type" = $2 AND "steps"."id" = $3 ORDER BY "recipe_steps"."position" ASC  [["recipe_id", 3], ["stepable_type", "Step"], ["id", 10]]
      ↳ app/controllers/recipes_controller.rb:46
      StepIngredient Load (0.4ms)  SELECT "step_ingredients".* FROM "step_ingredients" WHERE "step_ingredients"."step_id" = $1 AND "step_ingredients"."id" = $2  [["step_id", 10], ["id", 11]]
      ↳ app/controllers/recipes_controller.rb:46
      Measurement Load (0.4ms)  SELECT "measurements".* FROM "measurements" WHERE "measurements"."step_ingredient_id" = $1 AND "measurements"."id" IN ($2, $3, $4)  [["step_ingredient_id", 11], ["id", 15], ["id", 16], ["id", 17]]
      ↳ app/controllers/recipes_controller.rb:46
       (0.2ms)  COMMIT
      ↳ app/controllers/recipes_controller.rb:46
    Redirected to http://localhost:3100/recipes/3
    Completed 302 Found in 21ms (ActiveRecord: 3.3ms)
    
    Started GET "/recipes/3" for ::1 at 2019-02-19 15:55:21 -0500
    Processing by RecipesController#show as HTML