在 Rails 加入 3 个表

Join 3 tables on Rails

我有 3 张桌子:

一个播放列表有一个主题(不是唯一的,几个播放列表可能有相同的主题) 答案 的状态:真或假

我想查询给定主题的真实答案。

理论上,这应该有效:

Track.joins(:answers).where(answers:{status:true}).joins(:playlist).where(playlists:{theme: myGivenTheme})

实际上,它包括 .joins(:playlist),但每当我添加 where(playlists:...) 条件时都会失败。 我已经尝试 Track.includes(:playlist),试图适应 belongs_to,但也失败了,出现以下错误消息:

Track.joins(:answers).where(answers:{status:true}).joins(:playlist).where(playlist:{name:'French'}).count
 (2.1ms)  SELECT COUNT(*) FROM "tracks" INNER JOIN "answers" ON "answers"."track_id" = "tracks"."id" INNER JOIN "playlists" ON "playlists"."id" = "tracks"."playlist_id" WHERE "answers"."status" =  AND "playlist"."name" =   [["status", true], ["name", "French"]]
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "playlist"
LINE 1: ..."."playlist_id" WHERE "answers"."status" =  AND "playlist"...
                                                             ^
from /Users/pierre/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:672:in `exec_params'
Caused by PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "playlist"
LINE 1: ..."."playlist_id" WHERE "answers"."status" =  AND "playlist"...
                                                             ^

from /Users/pierre/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:672:in `exec_params'

我会推荐你​​生的sql

Track.find_by_sql('SELECT * FROM tracks t
JOIN answers a ON a.id = t.answer_id
JOIN playlist p ON p.id = t.playlist_id
WHERE status = true
AND theme = ?', myGivenTheme);

假设您使用列的约定

您可以select特定的列,轨道模型上不存在的列将作为其中的一部分添加

您也可以一次加入两个表

Tracks.joins(:answers, :playlists)

我注意到您在 where

中使用单数加入 :playlist 和复数 :playlists

我终于解决了我的问题,希望这可能对我有所帮助,因为我没有找到很多关于这个特定语法主题的文档。正确的查询,找到整个用户的正确答案 (answer.status = true),对于给定的播放列表主题,名为 myGivenTheme 和给定的用户是:

Playlist.where(theme: myGivenTheme).joins(tracks: :answers).where(answers:{status: true, user_id: self.id})