Home > Net >  Rails - How to make an association on create for self referenced model?
Rails - How to make an association on create for self referenced model?

Time:11-12

I have a self_referenced model (category) :

class Category < ApplicationRecord
    has_many :sub_themes_association, class_name: "SubTheme"
    has_many :sub_themes, through: :sub_themes_association, source: :sub_theme
    has_many :inverse_sub_themes_association, class_name: "SubTheme", foreign_key: "sub_theme_id"
    has_many :inverse_sub_themes, through: :inverse_sub_themes_association, source: :category

    accepts_nested_attributes_for :sub_themes
end

I would like to create a category model with his sub_themes association in the same form.

For example Digital => category and SEO & Coding => sub_themes

class Admin::CategoriesController < AdminController

  def index
    @categories = Category.all
  end

  def new
    @category = Category.new
    @sub_themes = @category.sub_themes.build
  end

  def create
    @category = Category.new(category_params)
    if @category.save
      redirect_to admin_categories_path
    else
      render :new
    end
  end

  private

  def category_params
    params.require(:category).permit(
      :name,
      sub_theme_attributes: [
        sub_theme_ids:[]
      ]
    )
  end
end

And the form :

<%= simple_form_for [:admin,@category] do |f| %>
  <%= f.error_notification %>
  <%= f.input :name %>
  <%= f.association :sub_themes, as: :select, collection: Category.all, input_html: { multiple: true } %>
  <%= f.submit "Enregister" %>
<% end %>

The form is properly displayed, but, on create, I get an error and the associations are not persisted.

Unpermitted parameter: :sub_theme_ids

CodePudding user response:

Its a very common missconception that you need nested attributes for simple assignment (of existing records) when thats not the case. All you need is whitelist category[sub_theme_ids][]:

def category_params
  params.require(:category).permit(
    :name,
    sub_theme_ids: []
  )
end

accepts_nested_attributes_for is only needed if you want to create a category and its subthemes in the same form. In that case you need to use fields_for (which is wrapped by simple form as simple_fields_for):

<%= simple_form_for [:admin,@category] do |f| %>
  <%= f.error_notification %>
  <%= f.input :name %>
  <%= f.association :sub_themes, as: :select, collection: Category.all, input_html: { multiple: true } %>

  <fieldset>
    <legend>Subthemes</legend>
    <%= f.simple_fields_for(:sub_themes) do |st| %>
      <%= st.input :name %>
    <% end %>
  </fieldset>

  <%= f.submit "Enregister" %>
<% end %>
def category_params
  params.require(:category).permit(
    :name,
    sub_theme_ids: [],
    sub_theme_attributes: [ :name ]
  )
end
  • Related