更新表单在多对多关系中根本不起作用

时间:2016-01-08 07:44:47

标签: ruby-on-rails ruby oracle

在我的应用程序中,配方和配料之间存在多对多关系,一切正常,但更新。

当我更新食谱时,我可以更新数据库中与食谱表相关的任何值,但不会修改成分

这是食谱模型

class Recipe < ActiveRecord::Base
    after_create :save_implementos
    after_create :save_ingredientes
    has_many :HasImplemento, dependent: :destroy
    has_many :HasIngrediente, dependent: :destroy


has_many :ingredientes, through: :HasIngrediente
has_many :implementos, through: :HasImplemento


    #CUSTOM SETTER#
def ingredientes=(value)
        @ingredientes = value
end

def implementos=(value)
        @implementos = value
        #raise @implementos.to_yaml
end


private

#Guarda los implemenos de una receta
def save_implementos
    #raise self.id.to_yaml
    @implementos.each do |implemento_id|
        HasImplemento.create(implemento_id: implemento_id, recipe_id: self.id) 
    end
end

def save_ingredientes
    #raise @ingredientes.to_yaml
    @ingredientes.each do |ingrediente_id|
        HasIngrediente.create(ingrediente_id: ingrediente_id, recipe_id: self.id)
    end

end

这是成分模型

class Ingrediente < ActiveRecord::Base
    has_many :has_ingredientes
    has_many :recipes, through: :HasIngrediente
end

,这是连接表

class HasIngrediente < ActiveRecord::Base
  belongs_to :recipe
  belongs_to :ingrediente
end

2 个答案:

答案 0 :(得分:0)

我想你忘记了食谱模型中的accepts_nested_attributes_for

accepts_nested_attributes_for :ingredients

答案 1 :(得分:0)

您的模型有很多non-conventional代码,这可能是他们无法按要求运行的原因:

  1. 使用snake_case定义您的关联(不是CamelCase
  2. 如果您要保存嵌套/关联数据,请使用accepts_nested_attributes_for
  3. 仅使用回调直接处理模型;不要与其他模特打交道
  4. #app/models/recipe.rb
    class Recipe < ActiveRecord::Base
        has_and_belongs_to_many :ingredientes
        has_and_belongs_to_many :implementos 
    
        accepts_nested_attributes_for :ingredientes, :implementos #-> if you wanted to create new ones
    end
    

    由于您只使用回调创建了联接表记录,因此您可以使用<<或填充collection_singular_ids值(,如果您正在使用现有值)记录):

    #app/controllers/recipes_controller.rb
    class RecipesController < ApplicationController
       def new
          @recipe = Recipe.new recipe_params
          @recipe.save
       end
    
       private
    
       def recipe_params
          params.require(:recipe).permit(:implementos_ids, :ingredientes_ids)
       end
    end
    

    这将允许您使用:

    #app/views/recipes/new.html.erb
    <%= form_for @recipe do |f| %>
       <%= f.collection_select :implementos_ids, Implementos.all, :id, :name %>
       <%= f.collection_select :ingredientes_ids, Ingrediente.all, :id, :name %>
       <%= f.submit %>
    <% end %>
    

    -

    我建议使用has_and_belongs_to_many,因为您似乎没有使用比两个模型引用更多的数据填充连接表。

    difference between has_many :through and has_and_belongs_to_manyhas_many :through,您可以在连接表中存储额外数据。如果您不需要,has_and_belongs_to_many更容易维护。

    因此,要直接回答您的问题,要更新recipe,您可以使用以下内容(使用我的更新代码):

    #app/views/recipes/edit.html.erb
    <%= form_for @recipe do |f| %>
       <%= f.collection_select :implementos_ids, Implementos.all, :id, :name %>
       <%= f.collection_select :ingredientes_ids, Ingrediente.all, :id, :name %>
       <%= f.submit %>
    <% end %>
    
    #app/controllers/recipes_controller.rb
    class RecipesController < ApplicationController
       def edit
          @recipe = Recipe.find params[:id]
       end
    
       def update
          @recipe = Recipe.find params[:id]
          @recipe.update recipe_params
       end
    
       private
    
       def recipe_params
          params.require(:recipe).permit(:implementos_ids, :ingredientes_ids)
       end
    end
    

    这将设置implementos_ids&amp; ingredientes_ids的{​​{1}}值,会自动更新关联。