Formtastic выберите с группировкой - PullRequest
8 голосов
/ 28 января 2010

Теперь с Formtastic у меня есть простой выбор:

= f.input :category, :as => :select, :include_blank => false, :collection => subcategories

Здесь я показываю только детские категории. Я использую плагин acts_as_tree для отношений родитель-ребенок. Я также хотел бы показать родительские категории.

Сгенерированный Formtastic выбор должен выглядеть следующим образом:

<select name="favoritefood">
  <optgroup label="Dairy products">
    <option>Cheese</option>
    <option>Egg</option>
  </optgroup>
  <optgroup label="Vegetables">
    <option>Cabbage</option>
    <option>Lettuce</option>
    <option>Beans</option>
    <option>Onions</option>
  <option>Courgettes</option>
  </optgroup>
  ⋮
</select>

Как использовать группировку в Formtastic select для модели с функционалом acts_as_tree? Кто-нибудь знает?

ОБНОВЛЕНО

Я понял, что это должно работать:

= f.input :category, :include_blank => false, :group_by => :parent

но не с ошибкой:

undefined local variable or method `object_class' for #<Formtastic::SemanticFormBuilder:0x87d3158>

Похоже, в Formtastic есть какая-то ошибка. Я просмотрел formtastic.rb и нашел объектный класс в detect_group_association метод:

  def detect_group_association(method, group_by)
    object_to_method_reflection = self.reflection_for(method)
    method_class = object_to_method_reflection.klass

    method_to_group_association = method_class.reflect_on_association(group_by)
    group_class = method_to_group_association.klass

    # This will return in the normal case
    return method.to_s.pluralize.to_sym if group_class.reflect_on_association(method.to_s.pluralize)

    # This is for belongs_to associations named differently than their class
    # form.input :parent, :group_by => :customer
    # eg. 
    # class Project
    #   belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id'
    #   belongs_to :customer
    # end
    # class Customer
    #   has_many :projects
    # end
    group_method = method_class.to_s.underscore.pluralize.to_sym
    return group_method if group_class.reflect_on_association(group_method) # :projects

    # This is for has_many associations named differently than their class
    # eg. 
    # class Project
    #   belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id'
    #   belongs_to :customer
    # end
    # class Customer
    #   has_many :tasks, :class_name => 'Project', :foreign_key => 'customer_id'
    # end
    possible_associations =  group_class.reflect_on_all_associations(:has_many).find_all{|assoc| assoc.klass == object_class}
    return possible_associations.first.name.to_sym if possible_associations.count == 1

    raise "Cannot infer group association for #{method} grouped by #{group_by}, there were #{possible_associations.empty? ? 'no' : possible_associations.size} possible associations. Please specify using :group_association"

  end

Действительно object_class не определено в этом методе, и в formtastic.rb нет приватного метода с таким именем. Но мы можем использовать : group_association для явного определения ассоциации.

- semantic_form_for ([:manager, @purchase_profile]) do |f|
  - f.inputs do
    = f.input :category, :include_blank => false, :group_by => :parent, :group_association => :children
  = f.buttons

но я столкнулся с другой ошибкой:

undefined method `children' for nil:NilClass

Я попытался выключить Acts_as_tree и написать свои собственные предположения. То же, что и Acts_as_tree, должно выглядеть так:

class Category < ActiveRecord::Base
  belongs_to :parent, :class_name => "Category", :foreign_key => "parent_id"
  has_many :children, :class_name => "Category", :foreign_key => "parent_id"
end

Ошибка такая же. Кто-нибудь может помочь?

Обновлено

Следующий маленький шаг. Этот код без Formtastic отлично работает:

= grouped_collection_select('', :category_id, top_categories, :children, :name, :id, :name, :include_blank => true)

p.s: top_categories - это вспомогательный метод с набором родительских категорий.

Последнее, что нужно перевести на синтаксис Formtastic:)

Ответы [ 3 ]

16 голосов
/ 05 августа 2012

Если у кого-то возникла такая же проблема, вы можете сделать следующее:

<%= f.input :category, :as => :select, :collection => option_groups_from_collection_for_select(ParentCategory.all, :categories, :name, :id, :name) %>

Ссылка от Rails API
Рекомендация от Джастина Френча (он упоминает об удалении: group_by)

1 голос
/ 30 марта 2010

Эй, я пытался решить конкретную проблему с помощью formtastic и обнаружил, что вы можете изменить запрос, использованный для построения списка, используя: find_options. Глядя на код, я увидел, что если вы не укажете: group_by, то список значений в конечном итоге сводится к find (: all) объекта модели (в методе с именем find_raw_collection_for_column в formtastic.rb). Параметры после: all - это набор параметров, указанных в: find_options. Таким образом, вы можете применять любые условия или другие параметры, которые вы обычно используете в find (* args) (см. http://ar.rubyonrails.org/classes/ActiveRecord/Base.html#M000333). Лично я добавил это в свой оператор f.input:

: find_options => {: условий => {: country_id => @ business.country? @ business.country.id: nil}}

Сделав это, я ограничил оператор выбора для запроса только текущим идентификатором округа. Но вы должны иметь возможность использовать: group аналогичным образом, чтобы указать, кого вы хотите использовать в GROUP BY в вашем запросе, например:

: find_options => {: group => 'parent.id'}

Надеется, что это поможет.

0 голосов
/ 29 января 2010

Почему бы не попытаться создать свой список элементов в помощнике, а затем передать его в тег выбора?

Я не знаю много о formtastic или activ_as_tree, но если у вас возникают проблемы с его работой, как у вас выше, я думаю, что прибегать к созданию ваших опций перед передачей их вашему выбору вполне разумно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...