在我的 ActiveRecord 查询中,我需要在 select 方法中提供此信息:
(SELECT count(*) from likes where likes.spentit_id = spentits.id) as like_count,
(SELECT count(*) from comments where comments.spentit_id = spentits.id) as comment_count
当然,我将这两个作为字符串传递给 .select() 部分,但我想知道这样做的正确/替代方法是什么?
这是我试图调用的完整查询:
SELECT DISTINCT
spentits.*,
username,
(SELECT count(*) from likes where likes.spentit_id = spentits.id) as like_count,
(SELECT count(*) from comments where comments.spentit_id = spentits.id) as comment_count,
(SELECT count(*) from wishlist_items where wishlist_items.spentit_id = spentits.id) as wishlist_count,
(case when likes.id is null then 0 else 1 end) as is_liked_by_me,
(case when wishlist_items.id is null then 0 else 1 end) as is_wishlisted_by_me,
(case when comments.id is null then 0 else 1 end) as is_commented_by_me
FROM spentits
LEFT JOIN users ON users.id = spentits.user_id
LEFT JOIN likes ON likes.user_id = 9 AND likes.spentit_id = spentits.id
LEFT JOIN wishlist_items ON wishlist_items.user_id = 9 AND wishlist_items.spentit_id = spentits.id
LEFT JOIN comments ON comments.user_id = 9 AND comments.spentit_id = spentits.id
WHERE spentits.user_id IN
(SELECT follows.following_id
FROM follows
WHERE follows.follower_id = 9 AND follows.accepted = 1)
ORDER BY id DESC LIMIT 15 OFFSET 0;
这里的所有表都有各自的 ActiveRecord 对象。只是真的很困惑如何通过编写最少的 SQL 将此查询转换为“activerecord”/rails 方式。'9' user_id 应该是一个参数。
更新: 好的,这就是我同时做的事情,它比原始 SQL 语句要好得多,但对我来说仍然很难看:
class Spentit < ActiveRecord::Base
belongs_to :user
has_many :likes
has_many :wishlist_items
has_many :comments
scope :include_author_info, lambda {
joins([:user]).
select("username").
select("users.photo_uri as user_photo_uri").
select("spentits.*")
}
scope :include_counts, lambda {
select("(SELECT count(*) from likes where likes.spentit_id = spentits.id) as like_count").
select("(SELECT count(*) from comments where comments.spentit_id = spentits.id) as comment_count").
select("(SELECT count(*) from wishlist_items where wishlist_items.spentit_id = spentits.id) as wishlist_items_count").
select("spentits.*")
}
end
使用这些范围方法,我可以做到:
Spentit.where(:id => 7520).include_counts.include_author_info.customize_for_user(45)
稍微讲讲课。AUser
有很多Spentits
。A有Spentit
很多comments
和。likes
comments