MrTom_2020
@MrTom_2020 (と む)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

SQLを Active Record クエリインターフェイス に変換したい。

環境

ruby 2.5.1
rails 6.0.3.2
devise 4.7.2
postgre 12.3

アソシエーション

userモデル

  has_many:tags
  has_many:group_users
  has_many:groups,through: :group_users
group_use中間モデル

  belongs_to :group
  belongs_to :user
groupモデル

  has_many:group_tags
  has_many:tags,through: :group_tags
  has_many:group_users
  has_many:users,through: :group_users
group_tag中間モデル

  belongs_to :group
  belongs_to :tag
tagモデル

  has_many:group_tags,dependent: :destroy
  has_many:groups,through: :group_tags
  belongs_to:user

maigationファイル内記述を簡単に説明

user

  # おそらく今回の件とは関係がないため割愛します。
group_use

  t.references :group, foreign_key: true
  t.references :user, foreign_key: true
group

  # おそらく今回の件とは関係がないため割愛します。
group_tag

  t.references :group, foreign_key: true
  t.references :tag, foreign_key: true
tag

  t.references :user, foreign_key: true

やりたいこと

SQLを Active Record クエリインターフェイス に変換したい。

tags_controller.rb

  def index
    if user_signed_in?
      @tags=Tag.joins(:groups).where(user_id:current_user.id).distinct
  end

上のrubyコードを御覧ください。

@tags=Tag.joins(:groups).where(user_id:current_user.id).distinct

上記を使用し、一時はうまく行っていると思っていたのですが、
1つのタグをグループに登録し、ユーザー2人で共有したときに
タグをcreateしたユーザーしか、タグを見ることが出来ませんでした。

次に根本的にSQLでどうやるの??と考えたところ、以下でうまくいきました。

SELECT distinct "tags" FROM "tags"
INNER JOIN "group_tags" ON "group_tags"."tag_id" = "tags"."id"
INNER JOIN "group_users" ON "group_users"."group_id" = "group_tags"."group_id"
WHERE (group_users.user_id = 2) #2の部分にcurrent_user.idが入ります。
ORDER BY "id"

そこでこれをrailsにと

Tag.joins(:group_tags).joins(:group_users).where(group_users:{user_id:current_user.id})

とか

Tag.joins(:group_tags,:group_users).where(group_users:{user_id:current_user.id})

とか

Tag.joins(group_tags: :group_users).where(group_users:{user_id:current_user.id})

とか

Railsガイド Active Record クエリインターフェイス
を見ながら色々と試したのですが解決には至りませんでした。OTL

どなたかお詳しい方お教え願えないでしょうか?
よろしくお願いいたしますm(T-T)m

追記
なんとか自己解決出来ました。

Tag.joins(groups: :group_users).where(group_users:{user_id:current_user.id}).distinct.order(:id)

これでなんとか行けたと思います。
以下は参考まで

SELECT DISTINCT "tags".* FROM "tags"
INNER JOIN "group_tags" ON "group_tags"."tag_id" = "tags"."id"
INNER JOIN "groups" ON "groups"."id" = "group_tags"."group_id"
INNER JOIN "group_users" ON "group_users"."group_id" = "groups"."id"
WHERE "group_users"."user_id" = 2 #2current_user.id

0

1Answer

Your answer might help someone💌