Я знаю, что это немного старый, но у меня есть решение этой проблемы, используя simple_form. Я не уверен, что это лучшее решение, но оно действительно работает.
В основном проблема сводится к передаче в значение group_method. В моем случае у меня был класс, который должен был получить компанию current_users, к которой он принадлежит. Моя модель структуры/базы данных было так:
Тип -> Категория
В моем случае тип записи были глобальными и не относятся к конкретной компании. Однако записи о типовой модели принадлежали конкретной компании. Цель состоит в том, чтобы показать сгруппированный выбор с глобальными типами, а затем с категорией компании под ними. Вот что я сделал:
class Type < ActiveRecord::Base
has_many :categories
attr_accessor :company_id
# Basically returns all the 'type' records but before doing so sets the
# company_id attribute based on the value passed. This is possible because
# simple_form uses the same instance of the parent class to call the
# group_by method on.
def self.all_with_company(company_id)
Type.all.each do |item|
item.company_id = company_id
end
end
# Then for my group_by method I added a where clause that reuses the
# attribute set when I originally grabbed the records from the model.
def categories_for_company
self.categories.where(:company_id => self.company_id)
end
end
Таким образом, вышеизложенное определение типа. Для справки это мое определение класса категории.
class Category < ActiveRecord::Base
belongs_to :company
belongs_to :type
end
Тогда на моем контроле simple_form я сделал это:
<%= f.association :category, :label => 'Category', :as => :grouped_select, :collection => Type.all_with_company(company_id), :group_method => :categories_for_company, :label_method => :name %>
В принципе, вместо передачи в значение, которое мы хотим отфильтровать в: group_method свойство мы передаем его в на: свойства коллекции. Несмотря на то, что он не будет использоваться для получения родительской коллекции, он просто сохраняется для последующего использования в экземпляре класса. Таким образом, когда мы вызываем другой метод в этом классе, он имеет значение, которое нам нужно сделать для фильтрации.