通过循环类创建select_tag的最佳方法

时间:2015-06-05 12:23:42

标签: mysql ruby-on-rails ruby

我有这种情况:

class Category < ActiveRecord::Base

  has_many      :children,    :class_name => "Category",    :foreign_key => "parent_id"
  belongs_to    :parent,      :class_name => "Category",    :foreign_key => "parent_id"

  def self.for_select
    ?? DO SOMETHING ??
  end

end

我只需要为select_tag生成这样的选项:

Category 1
  - Subcategory 1
  - Subcategory 2
  - Subcategory 3
Category 2
  - Subcategory 4
  - Subcategory 5

如何在不使用循环查询强调数据库的情况下执行此操作?

实际上,我有类似的东西,但它执行的查询太多了:

def self.for_select
  ret = []
  Category.where(parent_id: nil).each do |m|
    ret << [m.name, m.id]
    m.children.each { |c| ret << ["- #{c.name}", c.id] }
  end
  return ret
end

2 个答案:

答案 0 :(得分:1)

目前尚不清楚您想要在选择选项中显示的内容。在这里,我假设“类别”是所有没有父母的类别,子类别是这些类别的直接子类。

在您的类别

#class methods section
class << self

  def select_options
    top_level_categories = Category.where(:parent_id => nil).includes(:children)
    top_level_categories.collect{|category| [[category.name, category.id]] + category.children.collect{|category| [" - #{category.name}, category.id]}}
  end

应返回

[["Category 1", 321], [" - Subcategory 1", 123], [" - Subcategory 2", 456]...etc]

然后,在您看来,做<​​/ p>

select_tag "foo", options_for_select(Category.select_options)    

答案 1 :(得分:0)

尝试类似:

class Category
  # ...

  scope :main_categories, -> { where(parent_id: nil) }

  def self.for_select
    main_categories.includes(:children).each_with_object([]) do |cat, ret|
      ret << [cat.name, cat.id]
      ret << cat.children.map { |sub| ["- #{sub.name}", sub.id] }
    end
  end
end

希望有所帮助!