创建新的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关联尝试删除关联,而不是尝试创建新关联(如果它们以前不存在),如果以前存在但是不再删除,则删除。< / p>
答案 0 :(得分:3)
你应该尝试使用&lt;&lt;运算符而不是=;
@dish.cuisines << Cuisine.where(:id => params[:dish][:cuisine_ids]).last
这应该添加而不是替换两个表中所需的ID。
答案 1 :(得分:2)
我认为答案源于我的问题:
为什么要更新HABTM关联
更新HABTM关联是什么意思?
<强> HABTM 强>
HABTM关联是collection of records,可以添加(<<
)或删除(.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") %>