Search code examples
ruby-on-railsnested-formsnested-attributesstrong-parameters

Rails 4: Strong parameters + nested attributes + multiple select


I have a model called TaxCategory, that has_many :tax_rates and accepts_nested_attributes_for :tax_rates, reject_if: :all_blank, allow_destroy: true.

TaxRates itself is a model, which, amongst other things, has_and_belongs_to_many :countries.

These relations work fine, and I am able to add and remove countries through the console.

However, I have a form for TaxCategory that contains fields_for :tax_rates do |g|.

Inside here, I have a

g.select :country_ids, Country.collect{|c| [c.name, c.id]}, {multiple: true}, {}

It submits to the tax_categories controller, which uses the following code to update the TaxCategory:

class TaxCategoriesController
  before_action :set_tax_category, only: [:show, :edit, :update, :destroy]

 ...*snip*...

  def update
     respond_to do |format|
      if @tax_category.update(tax_category_params)
        format.html { redirect_to [:dashboard,  @tax_category], notice: 'Tax Category was successfully updated.' }
        format.json { render :show, status: :ok, location: @tax_category }
      else
        format.html { render :edit }
        format.json { render json: @tax_category.errors, status: :unprocessable_entity }
      end
    end

    private

  def set_tax_category
    @tax_category = TaxCategory.find(params[:id])
  end

  def tax_category_params
    params.require(:tax_category).permit(:name, tax_rates_attributes:[:id, :rate,{country_ids: []}, :_destroy])
  end


end

However, this does not work; When submitting the form, only the very first Country is saved, and the Rails command line shows the Unpermitted parameter: country_ids message.

I think this is a problem that is caused by the params.permit, but I do not understand what I am doing wrong.

What is going wrong, and how can I fix it?


Solution

  • UPDATE

    I think I found the problem. Your sample params say country_ids: 1, in which it should instead be country_ids: [1] because it should have been an array / multiple values.

    Update the following into:

    g.select :country_ids, Country.collect{|c| [c.name, c.id]}, {}, {multiple: true}
    
    Unpermitted Params error feels like it is most likely `tax_category_params` is the problem. Can you try this def tax_category_params params.require(:tax_category).permit(:name, tax_rates_attributes: [:id, :rate, country_ids: [], :_destroy]) end