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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

Q&A

解決済

1回答

3271閲覧

Rails6のテーブルの結合・抽出について

shisha

総合スコア86

Ruby on Rails 6

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

0グッド

0クリップ

投稿2020/06/24 23:57

編集2020/06/25 05:26

前提・実現したいこと

Rails で、1対多の2つのテーブルを結合・抽出したいです。

具体的に、状況を話していきます。

2つのテーブルのうちの1つは中間テーブルで、外部キーとしてuser_id, post_id を持っています。
この中間テーブルを、linksとします。

中間テーブルlinksは、where links.user_id = current_user.id という形で抽出したいです。
ここでの current_user.idとは、ログインしているユーザーのIDの数値です。
(追記ですが、current_user は、テーブルではなく、別に定義されているメソッドであり、Userモデルのログインユーザーが格納され、current_user.id でログインユーザーのID(非負整数)が返ってくるような状況です。実際に、usersテーブルは存在しますが、今回は結合する必要はないと考えています)

そして、post と 抽出した中間テーブルlinks を 左外部結合で on post.id = links.post_id という条件で結合させたいです。

結果として、全てのpostsのデータが入っており、また中間テーブルにログインしてるユーザーのデータの関係があればそのログインユーザーのデータが入っているというテーブルを取得したいです。

該当のソースコード

ruby

1class PostController < ApplicationController 2 def index 3 # これだと中間テーブルでログインユーザーのデータがあるものは結合されるが、NULLのデータが作れない。 4 @posts = Link.where(user_id: current_user.id).joins("LEFT OUTER JOIN posts ON posts.id = links.post_id") 5 .select("posts.*", "posts.id AS post_id", "links.*") 6 end 7end

試したこと

includes, joins, left_joins
where, or, select
などのメソッドを試しました。

ruby

1class PostController < ApplicationController 2 def index 3 # 全データを結合したあとに、user_id = current_user.id OR user_id is NULLで取得したいが、ORの検索方法がうまくつくれませんでした 4 @posts = Post.joins("LEFT OUTER JOIN links ON posts.id = links.post_id") 5 .select("posts.*","links.*") 6 .where(links: {user_id: current_user.id}) 7 end 8end

具体的なテーブルの追記

追記です。
UserとPostの多対多であり、中間テーブルとしてLinkを設けています。
ここで、Linkには、user_idやpost_id以外にも、色々なデータhogeやfugaがあり、全てのカラムを取り出したい状況です。
また、Post側のデータは全て使いたい状況です。

linksテーブル

user_idpost_idhogefuga
11ax
13by
22cz
23di
31ej
32fk

postsテーブル

idcontents
1hello
2world
3ruby
4on
5rails


例えば、「ログインしてるユーザーが1人目のときはcurrent_user.id = 1」で、user_id = 1 のデータを残し、次のように抽出結合したいです。

idcontentshogefuga
1helloax
2worldNULLNULL
3rubyby
4onNULLNULL
5railsNULLNULL

また、2人目のときはcurrent_user.id = 2で、user_id = 2 のデータを残し、次のように抽出結合したいです。

idcontentshogefuga
1helloNULLNULL
2worldcz
3rubydi
4onNULLNULL
5railsNULLNULL

具体的なモデルの追記

モデル側のアソシエーションは、次のように書いてあります。

ruby

1# app/models/post.rb 2class Post < ApplicationRecord 3 has_many :links, class_name: "Link",foreign_key: "post_id", dependent: :destroy 4 has_many :users, through: :links 5end 6 7# app/models/link.rb 8class Link < ApplicationRecord 9 belongs_to :user, foreign_key: 'user_id' 10 belongs_to :post, foreign_key: 'post_id' 11end 12 13# app/models/user.rb 14# 使わないと思うのですが、一応Userモデルの方も書いておきます。 15class User < ApplicationRecord 16 has_many :links, class_name: "Link",foreign_key: "user_id", dependent: :destroy 17 has_many :posts, through: :links 18end

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

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

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

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

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

YT0014

2020/06/25 04:29

必要なカラムだけで良いので、対象となる全テーブルのcreate tableをご提示ください。2つのテーブルと言いながら、posts,links,current_userと3つのテーブルが提示されています。
YT0014

2020/06/25 04:32

postsからlinksを経由せずに、user_idを取得するリレーションはありますか? あるようなら、ご提示ください。
YT0014

2020/06/25 05:26

SQLとしては、LEFT OUTER JOIN links ON posts.id = links.post_id AND links.user_id = ? で、?にuser_id をセットすれば、ご要望の結果を取得できると思います。
shisha

2020/06/25 07:22

ありがとうございます @posts = Post.joins("LEFT OUTER JOIN links ON posts.id = links.post_id AND links.user_id = 1") Rails でこれだけだと、linksのテーブルに入ってるデータをとれるようにならず、困っています。 記事に追記したように前提としてlinks テーブルにhoge や fuga などのカラムがあるのですが、@posts.first.hoge でデータを取り出せるような状況を期待しています。
guest

回答1

0

ベストアンサー

アソシエーションがかけてるので

@posts = current_user.posts.includes(links)

で posts も links のカラムも取り出せます

投稿2020/06/25 17:07

編集2020/06/25 17:08
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問