Ruby on Rails /依靠自嵌套模型(has_many / belongs_to)

时间:2016-02-07 00:16:24

标签: ruby-on-rails

我有一个自嵌套的类别模型:function waitAll(promiseArray) { return $q.all(promiseArray).then(function(results) { if (promiseArray.length <= results.length) { // everything currently in the promiseArray is now done return results; } else { // there are some new things in the promiseArray so // wait until they are done return waitAll(promiseArray); } }); } var promises = [promise1, promise2, promise3]; waitAll(promises).then(function(results) { // all promises currently in the promises array are done }); promises.push(promise4); has_many自我

belongs_to

在视图中,我不仅要显示class Category < ActiveRecord::Base has_many :subcategories, class_name: "Category", foreign_key: "parent_id", dependent: :destroy belongs_to :parent_category, class_name: "Category", foreign_key: "parent_id" end ,还要显示所有嵌套子类别的数量

我怎么能得到它?

~~~更新:~~~

在类别控制器中,我从以下参数中获取当前类别:

@category.subcategories.count

现在我想在视图中使用(但以下示例并没有给我所有嵌套的子类别)

def show
    @category = Category.find(params[:id])
end

2 个答案:

答案 0 :(得分:4)

创建一个递归模型方法......

def deep_count
  count = subcategories.count
  subcategories.each { |subcategory| count += subcategory.deep_count }
  count
end

如果在您的设计中,孩子可能成为祖先的父母

(例如&#34; 4x4&#34; - &gt;&#34;吉普&#34; - &gt;&#34; SUV&#34; - &gt;&#34; 4x4&#34; - &gt ;. ..)

然后你最终可能会出现堆栈溢出。为避免这种情况,您可以跟踪类别,以确保您不会对它们进行两次深度计算......

def deep_count(seen_ids=[])
  seen_ids << id
  count = subcategories.count
  subcategories.where("id NOT IN (?)", seen_ids).each do |subcategory|
    count += subcategory.deep_count(seen_ids)
  end
  count
end

答案 1 :(得分:0)

作为@SteveTurczyn史诗回答的补充,可能希望使用其中一个hierarchy宝石(我们使用acts_as_tree)。

这不仅会提取您的has_many :subcategories关联,还会提供无数的功能,以便您更好地处理嵌套对象。

#app/models/category.rb
class Category < ActiveRecord::Base
   acts_as_tree order: "name"
end

这将允许您使用以下内容:

@category = Category.find x

@category.children           #-> collection of subcategories
@category.parent             #-> Category record for "parent"

@category.children.create name: "Test" #-> creates new subcategory called "test"

由于acts_as_tree使用parent_id,您无需更改数据库中的任何内容。

-

您仍然可以使用deep_count方法:

#app/models/category.rb
class Category < ActiveRecord::Base
  acts_as_tree order: "name"

  def deep_count
     count = children.count
     children.each {|child| count += child.deep_count }
     count
  end
end

我确信必须有一种计算“孩子”的方法,但我手边没有任何代码。

它的主要好处是显示您的类别的递归。例如,如果是Post has_many :categories

#app/views/posts/index.html.erb
<%= render @post.categories %>

#app/views/categories/_category.html.erb
<%= category.name %>

Subcategories:
<%= render category.children if category.children.any? %>

-

看起来比两个ActiveRecord关联更清晰。