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ページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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総合スコア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
総合スコア145184
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。