14
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

awesome_nested_setを使った入れ子構造のDB設計

Last updated at Posted at 2019-02-24

入れ子集合モデルとは

入れ子集合モデルとは、主にデータベースにカテゴリーなどの親、子、孫が入れ子のように紐ついているときによく使用する保存方法。
例:カテゴリーの情報をアプリケーション上で扱いたいとき。
メンズカテゴリー(親)の中にトップス(子)と時計(子)が入っており、トップスの中にテーラード(孫)が入っている。

図解してみた

先ほどの例を図解してみる。

Image from Gyazo

どのようにしてデータベース上で扱うのか

この表をデータベース上で表現するには、右辺と左辺の番号を利用する。
先ほどの図に番号が示してある。
この番号を使用して、どこからどこのカテゴリーかを明示してあげることでデータベース上の扱いを可能にする。

入れ子集合モデルでは、「lft」「rgt」カラムに左辺と右辺の番号を保存する。
図でいうと

  • メンズは「lft」→1、「rgt」→9
  • トップスは「lft」→2、「rgt」→6
  • テーラードは「lft」→3、「rgt」→5
    でカラムに入れることができる。

メソッドについてはgithub参考。

使用手順

今回はgithubに書いてある通り、categoryモデルを作り、ミニアプリを作ってみた。

マイグレーションID_create_categories.rb
class CreateCategories < ActiveRecord::Migration[5.2]
  def self.up
    create_table :categories do |t|
      t.string :name
      t.integer :parent_id, :null => true, :index => true
      t.integer :lft, :null => false, :index => true
      t.integer :rgt, :null => false, :index => true

      t.integer :depth, :null => false, :default => 0
      t.integer :children_count, :null => false, :default => 0
      t.timestamps
    end
  end

  def self.down
    drop_table :categories
  end
end

【必須のカラム】

  • parent_id
    • これは子ノードがどの親なのかを示すid。一番大きい親の場合にはNULLになる。
  • lft
    • 名前通り、カテゴリーの左側の数値を入れる。
  • rgt
    • こちらも名前通り、カテゴリーの右側の数値を入れる。

【オプションカラム】

  • depth
  • children_count

model

category.rb
class Category < ApplicationRecord
  acts_as_nested_set
end

・参考記事
Railsでawesome_nested_setを使って階層構造を作成する
https://ruby-rails.hatenadiary.com/entry/20150216/1424092796

14
16
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
14
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?