How to save in a proper way a HABTM relationship on Rails
Asked Answered
I

1

5

I actually need some advice from advanced Ruby/Rails developers on what's the common and proper way to save a has_and_belongs_to_many association?

Here is what I did, but to me it feels really dirty and I don't really like to see that code in my app :)

models/company.rb

class Company < ActiveRecord::Base
  has_and_belongs_to_many :type_taxes

  ## Add Type taxes association
  def insert_types_taxes( types_taxes )
    self.type_taxes.clear
    self.type_taxes << types_taxes
  end
end

models/taxe.rb

class Taxes < ActiveRecord::Base
  has_and_belongs_to_many :societes
end

controllers/societes_controller

class SocietesController < ApplicationController
  # I use basically the same code for the update method
  def create
    params[:societe][:type_taxes_ids] ||= []
    @societe = Societe.new( societe_params )
    @societe.user_id = current_user.id
    if @societe.save
      add_types_taxes_to_societe
      redirect_to societes_path
    else
      load_resources
      render :new
    end
  end

  private
    def add_types_taxes_to_societe
      types_taxes = TypeTaxe.find params[:societe][:type_taxe_ids]
      @societe.insert_types_taxes types_taxes
    end
end

When this work fine, it really feels dirty to me. It also doesn't tell me if the associations creation has been created with success or no.

Any suggestions are more than welcome to improve my skills and my code :)

Thanks

Imitative answered 19/9, 2013 at 23:41 Comment(0)
B
10

When you directly re-assign a HABTM association using =, it will remove join records that are not present in what you're assigning it to. That is to say:

types_taxes = TypeTaxe.find params[:societe][:type_taxe_ids]
@societe.types_taxes = types_taxes

is essentially the same as what you've got. It will delete and add records but only as needed, so if there's overlap, the overlapping records will simply stay assigned.

Bautram answered 19/9, 2013 at 23:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.