目标:用户登录,并查看他们订阅的电视节目的下一集节目列表。所以有三个常规表(Users,TvShows,Episodes)和一个连接表(Subscriptions,它们连接User和TvShow)。
模特:
has_many :users, through: :subscriptions
has_many :episodes
has_many :subscriptions
belongs_to :tv_show
has_many :tv_shows, through: :subscriptions
has_many :subscriptions
belongs_to :tv_show
belongs_to :user
要获取用户订阅的节目列表,我可以说current_user.subscriptions(includes: :tv_show).all
。
这里是我陷入困境的地方:我想选择当前用户的订阅,包括电视节目,以及包括该节目的剧集。
如果可能,更具体地说,我只想包含一个剧集:可能airtime
值最低的剧集(播出时间为纪元时间)> Time.now.to_i
(即下一集播出的剧集)。
我已尝试在文档和Google上搜索此内容,但对于我来说,用30个字或更少的字描述这是一个很难的问题,所以我没有太多运气来解决它。我会在这里得到一些帮助。
答案 0 :(得分:1)
尝试以下代码
current_user.subscriptions.includes({tv_show: :episodes}).where("episodes.airtime > ?", Time.now.to_i)
答案 1 :(得分:1)
将has_one关系添加到最新一集:
class TvShow
has_many :episodes
has_one :latest_episode, -> { order(:airtime) }, class_name: 'Episode',
end
User.eager_load(tv_shows: :latest_episode).find(1)
查询1
SELECT DISTINCT "users"."id" FROM "users"
LEFT OUTER JOIN "subscriptions" ON "subscriptions"."user_id" = "users"."id"
LEFT OUTER JOIN "tv_shows" ON "tv_shows"."id" = "subscriptions"."tv_show_id"
LEFT OUTER JOIN "episodes" ON "episodes"."tv_show_id" = "tv_shows"."id"
WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
查询2
SELECT
"users"."id" AS t0_r0,
"users"."created_at" AS t0_r1,
"users"."updated_at" AS t0_r2,
"tv_shows"."id" AS t1_r0,
"tv_shows"."created_at" AS t1_r1,
"tv_shows"."updated_at" AS t1_r2,
"episodes"."id" AS t2_r0,
"episodes"."tv_show_id" AS t2_r1,
"episodes"."airtime" AS t2_r2,
"episodes"."created_at" AS t2_r3,
"episodes"."updated_at" AS t2_r4
FROM "users"
LEFT OUTER JOIN "subscriptions"
ON "subscriptions"."user_id" = "users"."id"
LEFT OUTER JOIN "tv_shows"
ON "tv_shows"."id" = "subscriptions"."tv_show_id"
LEFT OUTER JOIN "episodes"
ON "episodes"."tv_show_id" = "tv_shows"."id"
WHERE "users"."id" = ? AND "users"."id" IN (1) [["id", 1]]