В моем запросе ActiveRecord, мне нужно предоставить эту информацию в методе выбора:ActiveRecord выберите добавить счетчик
(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. Просто очень смутно, как преобразовать этот запрос в «activerecord»/rails с записью наименьшего количества SQL. «9» user_id должен быть параметром.
Update: Ok так вот что я сделал inmean время, это намного лучше, чем необработанного заявление 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)
Немного о классах. A User
имеет много Spentits
. A Spentit
имеет множество comments
, likes
и comments
.
Эти два выбора должны быть частью одного запроса, или эти два отдельных? «проведенные» - это * один конкретный объект Spentit, не так ли? – kiddorails
@kiddorails Одиночный запрос, и да, потраченные объекты имеют тип Spentit. Я обновил весь свой запрос, чтобы вы знали, что именно я ищу. – 0xSina
Хорошо, можете ли вы описать, с точки зрения связанных объектов, какую информацию вы пытаетесь получить? В принципе - не думайте в терминах SQL вообще, подумайте сначала в терминах «У меня есть куча объектов со ссылками и отношениями» и определите свой запрос с точки зрения этих вместо SQL.SQL - это просто метод сериализации и хранения, а не * вещь *. – Narfanator