现在使用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中使用分组选择具有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 方法中找到了object_class:
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中没有具有该名称的privat方法。但我们可以使用: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语法:)
答案 0 :(得分:15)
如果有人遇到同样的问题,您可以执行以下操作:
<%= 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(他提到删除:group_by)
答案 1 :(得分:1)
嘿,所以我试图用formtastic解决一个特定的问题,并发现你可以使用:find_options修改用于构建列表的查询。查看代码,我看到如果你没有指定:group_by,那么值列表最终会归结为模型对象上的find(:all)(在formtastic.rb中名为find_raw_collection_for_column的方法中)。在:all之后的参数是由find_options指定的参数集。因此,您可以应用通常在find(* args)中使用的任何条件或其他参数(请参阅http://ar.rubyonrails.org/classes/ActiveRecord/Base.html#M000333)。就个人而言,我将此添加到我的f.input声明中:
:find_options =&gt; {:conditions =&gt; {:country_id =&gt; @ business.country? @ business.country.id:nil}}
通过这样做,我将查询的select语句限制为仅当前的县ID。但是你应该能够以类似的方式使用:group来在你的查询中指定你想要GROUP BY的人,比如:
:find_options =&gt; {:group =&gt; 'parent.id'}
希望这会有所帮助。
答案 2 :(得分:0)
为什么不尝试在帮助器中构建项目列表,然后将其传递给select标签?
我对formtastic或acts_as_tree知之甚少,但是如果你在上面的工作中遇到问题,我认为在将它们传递给你的选择之前构建你的选项是完全合理的。