8

现在有了 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)

ps:top_categories 是带有父类别集合的辅助方法。

最后一件事是将它翻译成 Formtastic 语法:)

4

3 回答 3

16

如果有人遇到同样的问题,您可以执行以下操作:

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


来自 Justin French的 Rails API 推荐参考(他提到删除 :group_by)

于 2012-08-04T21:55:07.010 回答
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 => {:conditions => {:country_id => @business.country ? @business.country.id:无}}

通过这样做,我将查询的 select 语句限制为仅当前县 ID。但是您应该能够以类似的方式使用 :group 来指定您想要在查询中对谁进行 GROUP BY,如下所示:

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

希望这会有所帮助。

于 2010-03-30T16:37:57.307 回答
0

为什么不尝试在帮助程序中构建项目列表,然后将其传递到 select 标记中呢?

我对 formtastic 或acts_as_tree 了解不多,但如果你在让它像上面那样工作时遇到问题,我认为在将它们传递给你的选择之前先构建你的选项是完全合理的。

于 2010-01-29T08:01:24.193 回答