Reputation: 8548
Creating new HABTM associations work just fine for me, but each time I try to update them, all the associations get deleted.
This is how my update action looks like.
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
My dish params looks like so
def dish_params
params.require(:dish).permit(:title, :desc, cuisine_ids: [:id], diet_ids: [:id])
end
If on edit I click on two checkboxes of cuisine, the logs while on step (2) reads this (Note only Delete
and no update or Insert for cuisine_dishes
table)
(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)
Question : Why does updating HABTM associations try to delete the association, instead of trying to create new ones if they do not previously exist, and delete if they previously existed but do not any more.
Upvotes: 2
Views: 2503
Reputation: 76774
I think the answer is born from a question I have:
Why does updating HABTM associations
What do you mean by updating HABTM associations?
HABTM
HABTM associations are a collection of records which are available to add (<<
), or remove (.delete
). You can't "update" a record with this - you either have to add or delete (mainly because they don't have primary keys
.
We do that in this way:
#app/controllers/your_controller.rb
def update
@obj = Model.find params[:id]
@obj2 = Model2.find params[:model_2]
@obj.asssociative_data << @obj2
end
The problem you have is you're passing new data to your habtm
association. The only way you can "update" this data is to overwrite all the current collection with the new ids
you've posted (which is what I think you're doing)
Fix
The way to fix this will be to make sure you're passing the correct params in your cuisine_ids: [:id]
, diet_ids: [:id]
strong_params
method.
I think your problem will be that you're passing :id
only. I think Rails expects you to pass :cuisine_ids
and :diet_ids
, with those arrays populated with numerical data only, like with our code:
def profile_params
params.require(:profile).permit(attributes(Profile), :image, :category_ids)
end
To do this, you'll have to do this with your form:
<%= f.select(:category_ids, Category.all, prompt: "Category") %>
Upvotes: 2
Reputation: 254
You should try using the << operator instead of = ;
@dish.cuisines << Cuisine.where(:id => params[:dish][:cuisine_ids]).last
This should add and not replace the required ids in both the tables.
Upvotes: 3