56
64

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 5 years have passed since last update.

多階層カテゴリーの実装

Last updated at Posted at 2019-01-25

多階層カテゴリーの実装

多階層カテゴリー...
rails初心者の方にとっては中々高い壁ではないでしょうか。
そこで、rails初心者である私が実装した三層のカテゴリー検索機能について、説明させて頂ければと思います。
少しでも参考になれば幸いです。

必要なテーブル、カラム

categoriesテーブル
・nameカラム
・parent_idカラム

上記テーブル、及びカラムが必要となります。
parent_idという謎のカラムが存在しますが、説明は後程。

アソシエーション

今回は一つのテーブルで、一層目のカテゴリー、二層目のカテゴリー、三層目のカテゴリーと、全てのカテゴリーを取得出来るよう実装します。

そのためにまず、下記のようなアソシエーションを組みます。

category.rb
class Category < ApplicationRecord
  belongs_to :parent, class_name: :Category
  has_many :children, class_name: :Category, foreign_key: :parent_id
end

...上記を見てこう思わないでしょうか。

・なんでcategoryモデルからcategoryモデルにアソシエーション組んでんの?
・そもそもparentとchildrenって何?

これは自己結合モデルというアソシエーションの組み方で、一つのデータベースモデルに全カテゴリーを格納したいけれども、親カテゴリーと子カテゴリーの関係も追えるようにしたい...
そういった時に使用することで、任意のデータの取得が可能になります。

データベース

次に下記のように

categoriesテーブルのデータベース
id name parent_id
1 レディース ""
2 トップス 1
3 パンツ 1
4 1
5 Tシャツ 2
6 セーター 2
7 パーカー 2

parent_idに親カテゴリーのidを入れるよう、データベースにカテゴリーを登録してください。seedファイル等を利用して登録すれば良いと思います。

データの取得

上記アソシエーションの定義、及びカテゴリーの登録によって

@category = Category.find(1)
# 下記でレディースに紐付く子カテゴリーであるトップス、パンツ、靴を全て取得出来る
@category.children
----------------------------
@category = Category.find(2)
# 下記でトップスに紐付く子カテゴリーであるTシャツ、セーター、パーカーを全て取得出来る
@category.children
# 下記でトップスの親カテゴリーであるレディースのカテゴリーを取得出来る
@category.parent
----------------------------
@category = Category.find(5)
# 下記でTシャツの親カテゴリーであるトップスのカテゴリーを取得出来る
@category.parent
# 下記でTシャツの親の親のカテゴリーであるレディースのカテゴリーを取得出来る
@category.parent.parent

任意のカテゴリーを引っ張ってこれるようになります。

また、少し発展的な話をすると

@category = Category.find(params[:id])
  @categories = [
    # 下記で@categoryを取得
    @category,
    # 下記で@categoryの子カテゴリーを全て取得
    @category.children,
    # 下記で@categoryの子カテゴリーの子カテゴリーを全て取得
    @category.children.map { |category| category.children }
  ].flatten.compact

この記述で、idの部分に任意のidを入れると、そのidに関連した全ての子カテゴリーを取得することが出来ます。
例えば、上記の例だとidに1を入れることで、レディース関連のカテゴリーを全て取得することが可能です。

※一番下に記述されているflattenメソッド、compactメソッドはそれぞれ
・複雑化した配列を平坦に返す
・配列の中で発生するnilを取り除いた新しい配列を返す
という機能を持っています。

これらのメソッドを応用することで、何とか三層のカテゴリー検索機能を実装することが出来ました!

参考

56
64
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
56
64

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?