Last Updated: January 12, 2017
·
5.895K
· caulfield

Grouped multiselect with simple_form and nested_set

Let's create custom simpleform input to your nestedset's association. For example, you have model Category

Category.count # => 4
Category.first.name # => 'Root'
Category.first.children.map &:name # => ['Child1', 'Child2', 'Child3']

And you allow user to have(and belongs to) many categories:

simple_form_for @user do |f|
  f.association :categories

This code create simple multiselect, but we need some option groups and have some problems too. For example user can chose Root category

Let's create simple_form custom input:

class GroupedMultiSelectInput < SimpleForm::Inputs::GroupedCollectionSelectInput
  def input_html_options
    super.merge!(multiple: true)
  end

  def grouped_collection
    @grouped_collection ||= begin
      scope = options.delete(:scope)
      scope.includes(:children).roots
    end
  end

  def group_method
    @group_method ||= :children
  end

  def group_label_method
    detect_collection_methods.first
  end
end

Found docs here: https://github.com/plataformatec/simple_form/wiki/Adding-custom-input-components

And now your form:

simple_form_for @user do |f|
  f.association :categories, as: :grouped_multi_select_input, scope: Category, include_blank: false

And it works!