bismoney
@bismoney

Как правильно составить запрос?

Привет друзья, каша в голове как это объединить сократить?

Выборка для одного блока
@posts_main = Post.where('...').limit(1)

Дальше мне надо выбрать 15 последних записей и исключить post_main
Post.where('id != ?', @posts_hot.map(&:id)).limit(15).order('created_at DESC')


Вот тут начинаются вопросы, тут мы выбираем 15 записей, но мне надо выводить не всегда 15

1) К примеру мне надо проверить эти 15 записей на quote IS NOT NULL и посчитать сколько их из 15.
Post.joins(:post_asset).where('quote IS NOT NULL').limit(15).order('created_at DESC').count


2) А так-же мне надо посчитать в этих же 15 записях сколько с post_block_id = 2
Post.where('post_block_id = 2').limit(15).order('created_at DESC').count


Так же эти две выборки надо делать исключив 'id != ?', @posts_hot.map(&:id)) новость из блока post_main
Теперь мне надо значения количества 1 и 2 вычесть из 15
То есть там где мы в самом начале делали выборку, вместо 15 надо выводить 15 минус числа тех двух запросов.

К примеру
test1 = Post.where('post_block_id = 2').limit(15).order('created_at DESC').count
test2 = Post.joins(:post_asset).where('quote IS NOT NULL').limit(15).order('created_at DESC').count
test = 15 - test1 - test2


Post.where('id != ?', @posts_hot.map(&:id)).limit(<b>test</b>).order('created_at DESC')


Как все это должно выглядеть правильно?
  • Вопрос задан
  • 159 просмотров
Решения вопроса 1
либо фильтровать сразу в запросе

Post
  .where.not(id: @posts_hot.map(&:id))
  .where.not(id: Post.where(post_block_id: 2)) # magic number anipattern. лучше заменить на константу
  .where.not(id: Post.joins(:post_asset).where.not(post_asset: { quote: nil }))
  .order(created_at: :desc)
  .limit(15)


либо отфильтровать после запроса в коде

Post
  .includes(:post_asset)
  .where.not(id: @posts_hot.map(&:id))
  .order(created_at: :desc)
  .limit(15)
  .select { |post| post.post_block_id != 2 }
  .select { |post| post.post_asset.try :quote }
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы