質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

1877閲覧

Railsで階層構造(親子関係)のある複数選択可能なckeckboxを作成したい

sugamaan

総合スコア6

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2018/08/24 11:21

編集2018/08/25 06:18

前提・実現したいこと

Rails5にてシステムをつくっています。

![]
参照元https://tenshoku.mynavi.jp/

このような階層的なcheckboxを実装したいと考えているのですが、
・どのようなDB構造なのか?
・view側でどのように実装し、parameterを送り、保存処理を行えば良いか?
と、システム構築の検討がつきません。

試したこと

普段、複数のckeckboxの実装は、collection_check_boxesメソッドを利用しています。
また、複数のモデルへの保存処理は、fields_for + nested attributes を利用して実装した経験があります。

[参考]Railsでaccepts_nested_attributes_forを使ってNested Modelを新規作成するときの注意
[参考]Railsでaccepts_nested_attributes_forとfields_forを使ってhas_many関連の子レコードを作成/更新するフォームを作成

しかし、階層化+複数のcheckboxとなると、手が止まってしまいました。
過去に実装経験がある方、または実装イメージがつく方、ご教授して頂きたいですm(_ _)m

要件

上記のgif画像を元に、実行環境の例とCSVを作成しました。
下記の要件でなくても結構です。必要な場合に参考にして頂けたら幸いです。

要件を整理しました。
[要件]
・3層構造のチェックボックスを実現する
大項目:occupations
中項目:departments
小項目:roles
・チェックボックスはマスタデータ(occupations, departments. roles)を元に生成する
・これらの情報はDBに保存される
・親項目がチェックされた場合、その下の階層にあたる項目は自動的にチェックされる(例えば、大項目の営業 全て(occupatin id 1)が選択された場合、occupation_id 1を持つ、department(営業・代理店営業・ルートセールス・MR, 人材コーディネーター、コールセンター), そのdepartment_idを持つrole(営業法人向け…など)が選択される。)

[わからない点]
・大項目をcollection_check_boxesで実装した後、階層構造の子(departments)をcollection_check_boxesでチェックボックスを実装し、departmentsの子要素(roles)に対してcollection_ckeck_boxesで実装を行う?

テーブル

usersテーブル

ColumnTypeOptions
idstringnull: false
namestring

** [マスタデータ]**
occupationsテーブル

ColumnTypeOptions
idstringnull: false
namestring

deparmentsテーブル

ColumnTypeOptions
idstringnull: false
namestring

rolesテーブル

ColumnTypeOptions
idstringnull: false
namestring

CSV形式

*所々上記gifから項目名称を変更しています。

occupationsテーブル
name
全営業

departmetsテーブル
name, occupation_id
営業・代理店など,1
人材コーディネータ,1
コールセンターやカスタマーサポート,1

rolesテーブル
name, department_id
営業・企画営業 法人,1
営業・企画営業 個人,1
営業マネジャー・代理店営業,1
人生カウンセラー,2
専門コーディネータ,2
コールセンタ,3
オペレーション,3

実行環境

Ruby 2.3.1
Rails 5.0.5
mysql Server version: 5.6.34

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

・どのようなDB構造なのか?

ここに関してだけ。
私ならどれにチェックしたかを保存するテーブルとして、usres_rolesテーブルだけを作ります。

ColumnTypeOptions
user_id
role_id

occupations / departmets それぞれにチェックを付けたかをDB上には保存せず
表示上は
rolesテーブルの department_id が同じもの全てにチェックが付いていれば、そのdepartmentの項目にもチェックを付いてるように表示させます。
occupationsも同様です。

投稿2018/08/28 15:36

dobby618

総合スコア302

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sugamaan

2018/08/28 15:51 編集

回答ありがとうございます! 理由としては、role_idの情報があればdepartment、occupationの情報を参照することができるからかなと。 メリットは、無駄なDBをつくらず、余計なクエリを走らせなくて済む。 →パフォーマンスの向上。 デメリットとしては、情報の取り出しの際 user.users_roles.each do |user_role|  user_role.departments.each do |department|   department.occupations.each do |occupation|     p occupation.name   end  end end のように、userが選択したoccupationを取り出す場合、少し複雑になってしまうこと。 参考になりました!貴重なお時間頂きありがとうございます!
dobby618

2018/08/28 22:56

すみません、ちょっと勘違いしてたかも。 sugamaanさん記載してくれたテーブルに加えて、どれにチェックしたかをのデータを保存するために先ほどのusres_rolesテーブルを提案しました。 user_role/departments/occupationsと、階層ごとにテーブルを分けるのはいいと思いますよ!私もそうするかなー。 マスターデータだったら、activehashを検討してもいいのかも。 https://qiita.com/ryoff/items/88670edb3a656ca69d7b
sugamaan

2018/09/24 14:01

返信遅れました! 今回、階層ごとにテーブルを分け、collection_checkboxesをネストさせることによって実装しました。 親切な回答ありがとうございました!
guest

0

自己解決

概要

テーブルは3つ用意

大項目:occupations
中項目:departments
小項目:roles
(*サンプルは、大項目と中項目だけ使用)

解決方法

collection_check_boxesをネストさせて実装

サンプル

ruby

1= f.collection_check_boxes(:occupation_ids, Occupation.all, :id, :name_en) do |b| 2 = b.object.name_en 3 = b.label do 4 = b.check_box 5 = b.text 6 %ul 7 = f.collection_check_boxes(:department_ids, Department.all, :id, :name_en) do |s| 8 - if b.object.id == s.object.occupation_id 9 %li 10 = s.label do 11 = s.check_box 12 = s.text

labelも同じようにネストさせて書けば、表示させることはできますが、クエリの発行数がえぐいことになりました...。
これが、ベストプラクティスかはわかりませんが、1つの解決策として、参考になればなと思います。

より良い書き方、実装の仕方等ございましたら、教えて頂ければ幸いですm(_ _)m

投稿2018/09/24 14:05

編集2018/09/24 15:47
sugamaan

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問