Formtastic select with grouping
acts-as-tree, formtastic, grouping, optgroup, ruby-on-rails
Solution
In case anyone is having the same problem, you can do the following:
<%= f.input :category, :as => :select, :collection => option_groups_from_collection_for_select(ParentCategory.all, :categories, :name, :id, :name) %>
Reference from Rails API Recommendation from Justin French (he mentions removing the :group_by)
Problem
Now with Formtastic I have plain select: ``` = f.input :category, :as => :select, :include_blank => false, :collection => subcategories ``` Here I show only children categories. I use acts_as_tree plugin for parent-child relationship. I would like to show parent categories as well. Formtastic generated select should look like this one: ``` <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> ``` How to use grouping in Formtastic select for model with acts_as_tree functionality? Does anybody know? UPDATED I figured out that this should work: ``` = f.input :category, :include_blank => false, :group_by => :parent ``` but it doesn't with error: ``` undefined local variable or method `object_class' for #<Formtastic::SemanticFormBuilder:0x87d3158> ``` It looks like there is some bug in Formtastic. I have looked through formtastic.rb and found object_class in detect_group_association method: ``` 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 ``` Indeed object_class undefined in this method and there is no privat method with that name in formtastic.rb. But we can use :group_association to define association explicitly. ``` - 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 ``` but I ran into another error: ``` undefined method `children' for nil:NilClass ``` I tried swith off Acts_as_tree and write my own self-referenced assositions. The same as Acts_as_tree works should look like: ``` 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 ``` Error is the same. Can anybody help? Updated Next little step. This code without Formtastic works fine: ``` = grouped_collection_select('', :category_id, top_categories, :children, :name, :id, :name, :include_blank => true) ``` p.s: top_categories is helper method with collection of parent categories. The last thing is translate it into Formtastic syntax :)