1

私はツリーモデル(を使用closure_tree)であるモデルタグを持っており、gemのおかげで次のようなことができます:

Tag.includes(:children).first

その子を熱心にロードします。これで、子も使用するインスタンス メソッドができました。したがって、前述のクエリでタグを取得し、タグとその子を反復処理してこのインスタンス メソッドを呼び出すと、bulletgem は N+1 クエリを実行していると不平を言い、include(children). これは、子の子をロードしていないために発生するため、インスタンス メソッドを呼び出すときに、第 1 レベルのタグの各サブタグの子に対して個別のクエリを作成します。

次のようにすることでこれを解決できます。

Tag.includes(children: :children).first

この場合、ActiveRecord はタグ、その子、およびその子の子を積極的に読み込みます。ただし、これは 3 世代しかない場合に機能します。つまり、タグが祖父母であり、親 (ルート タグの子) と孫 (ルート タグの子の子) です。たとえば、私が4世代を持っている場合、私がしなければならないよりも:

Tag.includes(children: {children: :children}).first

したがってdepth、ルート タグの最も遠い孫の を特定できる場合、条件付きでクエリを作成する方法はありますか? 深さが 2 の場合は を使用includes(:children)し、深さが 3 の場合は を使用includes(children: :children)します。

4

2 に答える 2

0

私が思いつくことができる最善の解決策はこれです:

  def included_children(tag_id)
    depth = Tag.find(tag_id).leaves.last.depth
    eval(includes_string(depth))
  end

  def includes_string(depth)
    "{children: #{depth > 1 ? includes_string(depth - 1) : ':children'}}"
  end

私は最初depthに最も深い休暇を見つけます。これにより、 を何回呼び出さなければならないかがわかります:children。次に、深さに基づいて文字列を作成し、その文字列を評価してコード化し、それをincludesメソッドで使用します。このソリューションにはいくつかの欠陥があり、完全に汚れているため、改善の提案を歓迎します。ありがとうございました。

于 2014-12-16T09:25:50.677 に答える
0

次のドキュメントから判断すると、https://github.com/mceachen/closure_tree#usageを使用する必要があります

Tag.descendants
Tag.self_and_descendants

これにより、リーフで終了するまで、すべての子、サブ子などが取得されます。

于 2014-12-11T05:48:17.510 に答える