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

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

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

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

Q&A

解決済

1回答

2956閲覧

【Ruby on Rails】関連先がさらにある場合のデータの取得方法が分かりません

pecchan

総合スコア555

Ruby on Rails

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

0グッド

0クリップ

投稿2017/05/09 03:54

編集2017/05/09 03:56

いつも大変お世話になっております。

こちらの
【Ruby on Rails】関連モデルの最新行を取得したい
で教えていただき、直接のアソシエーション先の情報を持って来れました。
更に、その先までアソシエーションがある場合は、どのようにすれば取得出来ますでしょうか?

社員マスタの取得時に所属名(部門名+課名+グループ名)、
つまり紐づくそれぞれの名称も取得したいです。
所属モデルは、部id、課id、グループidのみを持っています。

以下が取得したいイメージですが、
社員名|所属部署|
田中|営業部第1課新宿グループ
斎藤|営業部第2課新橋グループ

現在は、以下のようにキーまでしか取得できてません。
社員名|所属部署|
田中|2,1,1
斎藤|2,2,2

所属モデル上にて部、課、グループをhas_manyし、
社員モデル上にて部の名称、課の名称、グループ名を取得するよう記述しましたが
ビューにて以下だとNoMethodError になりました。

ruby

1<%= employee.emp_group.dep_name %>

このような時はどういう方法になりますでしょうか?
どうぞ宜しくお願い致します。

社員モデル

ruby

1class Employee < ApplicationRecord 2 3 #所属マスタ 4 has_one :emp_group ,->{order 'start_date desc'},class_name: 'EmpGroup' 5 delegate :start_date,:dep_name,:sec_name,:grp_name,to: :emp_group,prefix: true 6 7 8end

所属モデル

ruby

1class EmpGroup < ApplicationRecord 2 3 #社員マスタとアソシエーション 4 belongs_to :employee 5 6 #部、課、グループとアソシエーション 7 has_many :department 8 has_many :section 9 has_many :group 10 11end 12 13

部門モデル

ruby

1class Department < ApplicationRecord 2 3 has_many :section 4 5 has_many :group 6 7 # 使用中のデータのみ返す 8 scope :using,->{where(dep_use: true)} 9 10end 11

課モデル

ruby

1class Section < ApplicationRecord 2 3 4 # 部門と紐づけ 5 belongs_to :department 6 7 has_many :group 8 9 # 使用中のデータのみ返す 10 scope :using,->{where(sec_use: true)} 11 12 13 14end 15 16

グループモデル

ruby

1class Group < ApplicationRecord 2 3 4 # 部門と紐づけ 5 belongs_to :department 6 7 # 課と紐づけ 8 belongs_to :section 9 10 # 使用中のデータのみ返す 11 scope :using,->{where(grp_use: true)} 12 13 14 15end 16 17 18

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

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

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

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

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

guest

回答1

0

ベストアンサー

dep_name,:sec_name,:grp_name methodがEmpGroupにないからです。
EmpGroupにもdelegateをつけましょう
※あと、よくわからないですがhas_manyじゃなくてbelongs_toなのでは?

ruby

1class EmpGroup < ApplicationRecord 2 3 #社員マスタとアソシエーション 4 belongs_to :employee 5 6 #部、課、グループとアソシエーション 7 belongs_to :department 8 belongs_to :section 9 belongs_to :group 10delegate :name,to: :department,prefix: :dep 11delegate :name,to: :section,prefix: :sec 12delegate :name,to: :group,prefix: :grp 13end

違うこうかも

ruby

1class EmpGroup < ApplicationRecord 2 3 #社員マスタとアソシエーション 4 belongs_to :employee 5 6 #部、課、グループとアソシエーション 7 belongs_to :department 8 belongs_to :section 9 belongs_to :group 10delegate :dep_name,to: :department,prefix: false 11delegate :sec_name,to: :section,prefix: false 12delegate :grp_name,to: :group,prefix: false 13end

うーん、レガシィー
あと

ruby

1<%= employee.emp_group.dep_name %>

ではなく

ruby

1<%= employee.emp_group_dep_name %>

ですよ

ひとつのmethodで最終的に必要な値の取得ができ
見通しがよくなるのがdelegateのメリットです。

投稿2017/05/09 04:44

編集2017/05/09 05:00
moke

総合スコア2241

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

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

pecchan

2017/05/09 05:40

moke様 なるほど! EmpGroupから必要なのは1つのみなので、 has_manyじゃなくてbelongs_toなのですね!! delegate、非常に便利ですね(*_*) 有難う御座いました!
moke

2017/05/09 06:02 編集

違います。 model_idを持っているほうがbelongs_toです。 持っていない方(持たれている方)は一対一対応でもhas_oneと書きます。
pecchan

2017/05/09 06:01

え。Departmentモデルのことでしょうか?!
moke

2017/05/09 06:16 編集

DepartmentとEmpGroupが1:Nだったら departments :id :name empgroups :id :department_id department.empgroups なので department has_many :empgroups empgroup.departmentなので empgroup belongs_to :department です。 DepartmentとEmpGroupが1:1で さらに departments :id :name empgroups :id :department_id だったら department has_one :empgroup empgroup belongs_to :department となります 関係先の相手のidを持っているモデルがbelongs_to 相手先モデル名 となります。 あとhas_manyの場合必ず相手のモデル名は複数になります。
pecchan

2017/05/09 06:29

moke様 度々失礼します。 私の見当違いでしたらすみません。 ご指摘はDepartmentモデルのことと仮定してご説明致します。 部、課、グループは 親、子、孫の関係になっており 部(Department)が決まれば課(Section)が決まり、 課(Section)が決まればグループ(Group)が決まります。 部(Department)が1で 課(Section)Nとなります。 よって部(Department)はhas_many 課(Section)から見れば belongs_to でmoke様のご指摘通りと思うのですが・・・。
pecchan

2017/05/09 06:32

あ。コメントが入れ違いになってしまった・・・
pecchan

2017/05/09 06:32

DepartmentとEmpGroupの関係ですね。
moke

2017/05/09 06:44 編集

すみません EmpGroupから必要なのは1つのみなので、 has_manyじゃなくてbelongs_toなのですね!! という理解が間違っているという意味で 違いますと書きました。 enployee has_one :empgroup みたいなものもあって、 enployeeから必要なのは1つのみなので、 has_manyじゃなくてhas_oneなのですね!! なら正解です。 で、has_oneとbelongs_toの違いはどうゆう時っていうと 相手のmodelのidを持っているか否かって話ですよ。 といいたかったんです。言葉足らずでした。
pecchan

2017/05/09 06:47

moke様 いえ、とんでもないです。 この辺りはややこしい所ですし、 という言い訳にさせて下さい^^; 間違った理解を正してくださって感謝してます。 アソシエーションを復習する機会になりました。 本当に有難う御座います。
moke

2017/05/09 07:02

誤解が解けてよかったです^^; あと、ないとは思いますが、delegateは グループや課が抜けていたりすると 思いっきりエラーを吐きますのでそういう場合は オプションでallow_nil: ture ってのを追加すると幸せになれます。 また、一覧表なのでEmployee.allをする時joinsだけでなく references({emp_groups: [:department,:group]})みたいにして あらかじめ取得しておかないとn+1問題が発生するので注意です。
pecchan

2017/05/09 07:36

moke様 追加情報有難う御座います。 実はすでにそのエラーが出て、対処しました^^; オプションで回避出来るんですね! referencesとn+1問題、今から勉強します!有難う御座います!
moke

2017/05/09 08:02 編集

違います~の代わりに これを書こうと思ってたんですよw n+1問題はrailsで割とあります。 一回ですむクエリをn+1回発行してしまうバグです。 referencesは関連レコードのデータをあらかじめ取得します。
pecchan

2017/05/10 00:07

moke様 今回、n+1問題も知るきっかけになって大変良かったです。 本当に有難う御座います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問