【问题标题】:Updating a HABTM model associations only deletes the associations更新 HABTM 模型关联只会删除关联
【发布时间】:2014-06-12 07:19:32
【问题描述】:

创建新的 HABTM 关联对我来说效果很好,但每次我尝试更新它们时,所有关联都会被删除。

这就是我的更新操作的样子。

def update
    params[:dish][:cuisine_ids] ||= []
    params[:dish][:diet_ids] ||= []

    @user = current_user
    @dish = @user.dishes_selling.find_by(:id => params[:id])

    @dish.cuisines = Cuisine.where(:id => params[:dish][:cuisine_ids]) ### (1) ###
    @dish.diets = Diet.where(:id => params[:dish][:diet_ids]) ### (1) ###

    if @dish
        respond_to do |format|
          if @dish.update(dish_params) ### (2) ###
            format.html { redirect_to dish_path(@dish), notice: 'Dish was edited.' }
          else
            format.html { render action: 'edit' }
          end
        end
    else
        flash[:error] = "You can only edit your dish!"
        render :index
    end
end

我的菜参数看起来像这样

    def dish_params
      params.require(:dish).permit(:title, :desc, cuisine_ids: [:id], diet_ids: [:id])
    end

如果在编辑时我点击了两个美食复选框,则在步骤 (2) 中的日志会读取此内容(仅注意 Delete 并且没有更新或插入 cuisine_dishes 表)

(0.1ms)  begin transaction
  SQL (0.4ms)  DELETE FROM "cuisines_dishes" WHERE "cuisines_dishes"."dish_id" = ? AND "cuisines_dishes"."cuisine_id" IN (7, 9)  [["dish_id", 61]]
  SQL (0.2ms)  UPDATE "dishes" SET "desc" = ?, "updated_at" = ? WHERE "dishes"."id" = 61  [["desc", "yema1245"], ["updated_at", "2014-06-12 06:57:36.622811"]]
   (5.5ms)  commit transaction
Redirected to http://localhost:3000/dishes/61
Completed 302 Found in 48ms (ActiveRecord: 13.7ms) 

问题:为什么更新HABTM关联会尝试删除关联,而不是尝试在以前不存在的情况下创建新的关联,如果之前存在但不再存在则删除。

【问题讨论】:

  • 如果它是您想要的答案,您能接受吗?

标签: ruby-on-rails ruby-on-rails-4 rails-activerecord has-and-belongs-to-many


【解决方案1】:

您应该尝试使用

@dish.cuisines << Cuisine.where(:id => params[:dish][:cuisine_ids]).last

这应该添加而不是替换两个表中所需的 ID。

【讨论】:

  • 哦,因为您是通过 id 查询,所以您可以使用 find:Cuisine.find(params[:dish][:cuisine_ids])欢呼!
【解决方案2】:

我认为答案来自我的一个问题:

为什么要更新 HABTM 关联

更新 HABTM 关联是什么意思


HABTM

HABTM 关联是一个 collection of records,可以添加 (&lt;&lt;) 或删除 (.delete)。你不能用这个“更新”一条记录——你要么必须添加要么删除(主要是因为他们没有primary keys

我们这样做:

#app/controllers/your_controller.rb
def update
   @obj = Model.find params[:id]
   @obj2 = Model2.find params[:model_2]

   @obj.asssociative_data << @obj2
end

您遇到的问题是您将新数据传递给您的habtm 关联。 唯一您可以“更新”此数据的方法是用您发布的新 ids 覆盖所有当前集合(我认为您正在这样做)


修复

解决此问题的方法是确保在 cuisine_ids: [:id]diet_ids: [:id] strong_params 方法中传递正确的参数。

我认为您的问题将是您仅传递:id。我认为 Rails 希望您通过 :cuisine_ids:diet_ids,这些数组仅填充数字数据,就像我们的代码一样:

def profile_params
    params.require(:profile).permit(attributes(Profile), :image, :category_ids)
end

为此,您必须使用表单执行此操作:

<%= f.select(:category_ids, Category.all, prompt: "Category") %>

【讨论】:

  • 感谢您的回复。我现在明白我的期望是不正确的,我现在可以正确地“更新”我的关联。但我仍然看到SQL (0.4ms) DELETE FROM "cuisines_dishes"@dish.update(dish_params) 上制作。我如何防止在该步骤中删除这些内容?
猜你喜欢
  • 2011-04-29
  • 2014-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多