前提・実現したいこと
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_id | post_id | hoge | fuga |
---|---|---|---|
1 | 1 | a | x |
1 | 3 | b | y |
2 | 2 | c | z |
2 | 3 | d | i |
3 | 1 | e | j |
3 | 2 | f | k |
postsテーブル
id | contents |
---|---|
1 | hello |
2 | world |
3 | ruby |
4 | on |
5 | rails |
↓
例えば、「ログインしてるユーザーが1人目のときはcurrent_user.id = 1」で、user_id = 1 のデータを残し、次のように抽出結合したいです。
id | contents | hoge | fuga |
---|---|---|---|
1 | hello | a | x |
2 | world | NULL | NULL |
3 | ruby | b | y |
4 | on | NULL | NULL |
5 | rails | NULL | NULL |
また、2人目のときはcurrent_user.id = 2で、user_id = 2 のデータを残し、次のように抽出結合したいです。
id | contents | hoge | fuga |
---|---|---|---|
1 | hello | NULL | NULL |
2 | world | c | z |
3 | ruby | d | i |
4 | on | NULL | NULL |
5 | rails | NULL | NULL |
具体的なモデルの追記
モデル側のアソシエーションは、次のように書いてあります。
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
回答1件
あなたの回答
tips
プレビュー