Multiselect agrupado com simple_form e nested_set

Vamos criar uma entrada de formulário simples personalizada para a associação do seu conjunto aninhado . Por exemplo, você tem categoria de modelo

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

E você permite que o usuário tenha (e pertença a) muitas categorias:

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

Este código cria multisseleção simples, mas precisamos de alguns grupos de opções e também temos alguns problemas. Por exemplo, o usuário pode escolher a categoria raiz

Vamos criar uma entrada customizada simple_form:

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

Documentos encontrados aqui: https://github.com/plataformatec/simple_form/wiki/Adding-custom-input-components

E agora seu formulário:

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

E funciona!