LoginSignup
0
0

More than 1 year has passed since last update.

多対多のアソシエーション間でのデータの取り方

Posted at

テックキャンプ現役受講生のアプリ開発Day16です。月末が終わりましたが、アプリ開発はまだまだ終わっていません。後、必要になる機能として、「作成したルームにジャンルをつける、テストコードをの記述、ページ全体のレイアウト」があります。正直後1週間強ないと終わりません。7月9日あたりを目標に終わらせようと思っています。今日は中間テーブルが必要なテーブル間で、データを取得する際に個人的に便利だなと思った方法についてアウトプットします。

アソシエーション

前提となるアソシエーションについて説明します。UserがRoomを作成することができ、Roomには複数の人が参加することができます。従って、User_roomの中間テーブルが必要になります。各テーブル間のアソシエーションを記述します。

user
class User < ApplicationRecord
  has_many :user_rooms
  has_many :rooms ,through: :user_rooms
end
room
class Room < ApplicationRecord
  has_many :user_rooms
  has_many :users, through: :user_rooms
end
user_room
class UserRoom < ApplicationRecord
  belongs_to :user
  belongs_to :room
end

①ある特定の複数のユーザーが作ったルームを全て取得

@users = User.where(id:[1,2, ...])
@rooms = Room.joins(:user_rooms).where(user_rooms:{user_id:@users.ids})

@usersのIDを利用し、中間テーブルのuser_roomsで検索したいユーザーを指定。roomとUser_roomを結合しているため、中間テーブルで欲しいUserを取得した段階で、欲しいルームも取得できる。

別の方法

user_rooms = UserRoom.where(user_id:[1,2, ...])
@rooms = Room.where(id:user_rooms.pluck(:room_id))

user_roomで特定の複数のユーザーを取得する。次に、pluckでRoom_userを配列に変換する。

もちろん他にもアソシエーションを使った方法等もあリマス。

②roomを新規作成順に取得

@rooms = Room.order(created_at: "DESC")

③roomの参加者が多い順に取得

@rooms = Room.joins(:user_rooms).group(:room_id).order('count(user_id) desc')

まず、中間テーブルでroom_idごとにまとまりを作る。
次に、各room_idごとに含まれるUser_idの数を数えて、降順に並び替える。
最後に、RoomとRoom_userを結合し、ルームを取得する。

参考になったサイト

初心者なら熟読したいサイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0