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

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

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

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

Q&A

解決済

2回答

1043閲覧

Railsのリレーションについての質問です。

crypto_chrono

総合スコア11

Ruby on Rails

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

0グッド

0クリップ

投稿2017/11/18 17:19

Railsのリレーションについての質問です。

ruby

1 2user.rb 3has_many :orders 4 5order.rb 6belongs_to :user 7has_many :order_details 8 9order_details.rb 10belongs_to :order 11

ユーザーはたくさんの注文を持っており、さらに注文はたくさんの注文詳細がある。

このような時に、どのようにすれば

ruby

1ユーザーが持っている注文詳細の全てを表示 2user.order_details 3 4注文詳細からユーザーを返す 5order_detail.user

どのようにすることで、ユーザーの注文一覧・注文詳細からユーザーを特定することができますか?
よろしくお願いします。

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

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

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

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

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

guest

回答2

0

orderDetail.order.user で user を取得できます。
OrderDetail.joins({:order => :user}).where('name = ?', 'kato')で ユーザー名で指定したユーザーに紐づいている order_detail をすべて取得できます。

irb での操作例を示します。

注文詳細からユーザーを返す

ruby

1irb(main)> OrderDetail.find_by(id: 1).order.user 2 OrderDetail Load (0.2ms) SELECT "order_details".* FROM "order_details" WHERE "order_details"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] 3 Order Load (0.3ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] 4 User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] 5+----+------+-------------------------+-------------------------+ 6| id | name | created_at | updated_at | 7+----+------+-------------------------+-------------------------+ 8| 1 | kato | 2017-11-19 02:01:30 UTC | 2017-11-19 02:01:30 UTC | 9+----+------+-------------------------+-------------------------+ 101 row in set 11

指定したユーザーが持っている注文詳細の全てを表示

ruby

1irb(main)> OrderDetail.joins({:order => :user}).where('name = ?', 'kato') 2 OrderDetail Load (0.3ms) SELECT "order_details".* FROM "order_details" INNER JOIN "orders" ON "orders"."id" = "order_details"."order_id" INNER JOIN "users" ON "users"."id" = "orders"."user_id" WHERE (name = 'kato') 3+----+----------+--------+-------+--------+-------------------------+-------------------------+ 4| id | order_id | amount | price | item | created_at | updated_at | 5+----+----------+--------+-------+--------+-------------------------+-------------------------+ 6| 1 | 1 | 1 | 100 | fish_a | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 7| 2 | 1 | 2 | 200 | fish_b | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 8| 3 | 2 | 1 | 10 | fish_a | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 9| 4 | 2 | 2 | 20 | fish_b | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 10+----+----------+--------+-------+--------+-------------------------+-------------------------+ 114 rows in set

以下に 上の操作をした時の User, Order, OrderDetail の状態を示します。

ruby

1irb(main)> User.all 2 User Load (0.2ms) SELECT "users".* FROM "users" 3+----+--------+-------------------------+-------------------------+ 4| id | name | created_at | updated_at | 5+----+--------+-------------------------+-------------------------+ 6| 1 | kato | 2017-11-19 02:01:30 UTC | 2017-11-19 02:01:30 UTC | 7| 2 | tanaka | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 8+----+--------+-------------------------+-------------------------+ 92 rows in set 10 11irb(main)> Order.all 12 Order Load (0.1ms) SELECT "orders".* FROM "orders" 13+----+---------+-----------+-------------------------+-------------------------+ 14| id | user_id | memo | created_at | updated_at | 15+----+---------+-----------+-------------------------+-------------------------+ 16| 1 | 1 | kato_01 | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 17| 2 | 1 | kato_02 | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 18| 3 | 2 | tanaka_01 | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 19+----+---------+-----------+-------------------------+-------------------------+ 203 rows in set 21 22irb(main)> OrderDetail.all 23 OrderDetail Load (0.2ms) SELECT "order_details".* FROM "order_details" 24+----+----------+--------+-------+--------+-------------------------+-------------------------+ 25| id | order_id | amount | price | item | created_at | updated_at | 26+----+----------+--------+-------+--------+-------------------------+-------------------------+ 27| 1 | 1 | 1 | 100 | fish_a | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 28| 2 | 1 | 2 | 200 | fish_b | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 29| 3 | 2 | 1 | 10 | fish_a | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 30| 4 | 2 | 2 | 20 | fish_b | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 31| 5 | 3 | 3 | 100 | beaf_a | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 32| 6 | 3 | 4 | 200 | beaf_b | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 33+----+----------+--------+-------+--------+-------------------------+-------------------------+ 346 rows in set

追記: 2017-11-19 11:30
User に has_many :order_details, through: :orders を追加して、
user.irder_detail をつかった場合は次のようになります。
(SQL として 2 つの SELECT が発行されています。 joins を使った場合は 1 つの SELECT でした。)

ruby

1irb(main):003:0> User.find_by(name: 'kato').order_details 2 User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."name" = ? LIMIT ? [["name", "kato"], ["LIMIT", 1]] 3 OrderDetail Load (0.3ms) SELECT "order_details".* FROM "order_details" INNER JOIN "orders" ON "order_details"."order_id" = "orders"."id" WHERE "orders"."user_id" = ? [["user_id", 1]] 4+----+----------+--------+-------+--------+-------------------------+-------------------------+ 5| id | order_id | amount | price | item | created_at | updated_at | 6+----+----------+--------+-------+--------+-------------------------+-------------------------+ 7| 1 | 1 | 1 | 100 | fish_a | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 8| 2 | 1 | 2 | 200 | fish_b | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 9| 3 | 2 | 1 | 10 | fish_a | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 10| 4 | 2 | 2 | 20 | fish_b | 2017-11-19 02:01:31 UTC | 2017-11-19 02:01:31 UTC | 11+----+----------+--------+-------+--------+-------------------------+-------------------------+ 124 rows in set

投稿2017/11/19 02:17

編集2017/11/19 02:25
katoy

総合スコア22324

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

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

0

ベストアンサー

has_many throughを使うことで、2段のhas_manyを通して使うことができるようになります・

ruby

1# user.rb 2has_many :orders 3has_many :order_details, through: :orders

こうすれば、user.order_detailsを使えるようになります。逆向きはdelegateを使うという手があります。

ruby

1# order_detail.rb 2 3delegate :user, to: :order, allow_nil: true

投稿2017/11/19 00:06

maisumakun

総合スコア145184

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

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

crypto_chrono

2017/11/19 01:48

ありがとうございます! うまくいきました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問