Amey
Amey

Reputation: 8548

Updating a HABTM model associations only deletes the associations

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

Answers (2)

Richard Peck
Richard Peck

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

Haider
Haider

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

Related Questions