LoginSignup
4
3

More than 5 years have passed since last update.

erbでn階層のツリーを表示する

Last updated at Posted at 2017-09-09

課題

1:N の 自己参照関係を持ったツリー状のモデルを、n階層のツリーとしてビュー内に静的に表示したい。

たとえば、以下のようなモデル:

$ ./bin/rails g model foo name:string foo_id:integer
app/models/foo.rb
class Foo < ApplicationRecord
  has_many :children, foreign_key: :foo_id, class_name: 'Foo'
end

解決方法

ERB内に表示用の再帰関数を定義して呼び出す方法で解決した。

app/views/foo/index.html.erb
<% def disp_tree(foo) %>
  <li>
    <span><%= foo.name %></span>
    <ul>
      <% foo.children.each do |f| %>
        <% disp_tree(f) %>
      <% end %>
    </ul>
  </li>
<% end%>

<ul>
  <% disp_tree(@root) %>
</ul>

適当にデータを入れて確認してみる:

app/controllers/foo_controller.rb
class FooController < ApplicationController
  def index
   @root = Foo.create!(name: 'root')

   @root.children << Foo.create!(name: 'n1')
   @root.children << Foo.create!(name: 'n2')
   @root.children << Foo.create!(name: 'n3')

   @root.children[0].children << Foo.create!(name: 'n1-1')
   @root.children[0].children << Foo.create!(name: 'n1-2')
   @root.children[0].children << Foo.create!(name: 'n1-3')

   @root.children[1].children << Foo.create!(name: 'n2-1')
   @root.children[1].children << Foo.create!(name: 'n2-2')
   @root.children[1].children << Foo.create!(name: 'n2-3')

   @root.children[2].children << Foo.create!(name: 'n3-1')
   @root.children[2].children << Foo.create!(name: 'n3-2')
   @root.children[2].children << Foo.create!(name: 'n3-3')

   @root.children[0].children[0].children << Foo.create!(name: 'n1-1-1')
   @root.children[0].children[0].children << Foo.create!(name: 'n1-1-2')
   @root.children[0].children[0].children << Foo.create!(name: 'n1-1-3')
  end
end

表示できた:

スクリーンショット 2017-09-09 23.46.34.png

補足

ERB内で直接関数宣言するのもアレなので、大きくなりそうならヘルパとパーシャルに切り出す感じで。

また同様の機能/表示を簡単に実現できそうな awesome_nested_setthe_sortable_tree というgemがあるとのことなので、こちらを使うほうがいいかもしれない。参考:

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3