Как я могу получить записи вокруг определенной записи в Ruby on Rails? - PullRequest
3 голосов
/ 25 февраля 2011

У меня есть модель под названием note. В настоящее время я получаю заметки, как это:

current_user.notes.order('date DESC, created_at DESC').limit(10).reverse!

Теперь мне нужно сделать следующее: Возьмите параметр note_id и верните 10 примечаний: одно из параметра и 9 других «вокруг» первого.

В идеале, 9 других нот должны быть распределены как 5 до основной ноты и 4 после (или 4 до и 5 после), исходя из порядка в первой строке выше.

Пример:

note note note note primary_note note note note note note

Иногда это будет невозможно. Например, если primary_note - вторая заметка пользователя, она должна вернуть следующее:

note primary_note note note note note note note note note

Или, если это последняя заметка, а у пользователя всего 3 заметки, она должна вернуть:

note note primary_note

Как я могу это сделать? Я использую ruby ​​1.9.2 и Rails 3.0.1

Ответы [ 2 ]

4 голосов
/ 25 февраля 2011

Я не думаю, что есть способ получить эти заметки одним запросом - вам понадобится как минимум два.Исходя из моего (несколько ограниченного) понимания SQL, единственный способ, которым вы должны это сделать:

  • Получить 4 примечания, которые идут "до" primary_note
  • Получить 4Примечания "после" primary_note
  • Объединение двух наборов

Что-то похожее на это (предупреждение: непроверенный код)

class Note < ActiveRecord::Base
  # on rails 3 I prefer class methods to named scopes.
  # they are equally "chainable" and have simpler syntax
  def self.notes_before(date, limit=4)
    self.where(['date >= ?', date]).order("date DESC, created_at DESC").limit(limit)
  end

  def self.notes_after(date, limit=4)
    self.where(['date <= ?', date]).order("created_at ASC, date ASC").limit(limit)
  end

  # Instance method
  def notes_around(limit=4)
    (Note.notes_before(self.date, limit) << self) + Note.notes_after(self.date, limit)
  end
end

Использование:

n = Note.new(:date => Date.yesterday)
n.notes_around # returns the 9 notes around n, plus n
n.notes_around(40) # returns 81 notes

# in addition:
Note.notes_before(Date.today, 40) # last 40 notes
Note.notes_after(Date.today, 10).where(:color => 'blue') # chainable

Но я не мог придумать «цепной метод класса».Возможно, я не знаю достаточно SQL.

В идеале, 9 других заметок будут выделены как 5 до основной ноты и 4 после (или 4 до & 5 после), в зависимости от порядка впервая строка выше

Я не понимаю, как вы определяете, что вам нужно "4" или "5" в этом контексте.Поэтому я предполагаю, что вы это знаете.

2 голосов
/ 25 февраля 2011

Вы можете использовать условие диапазона в вашем запросе

class Note
  scope :around_note_id, lambda { |id| where(:id => range_for_search(id) }

  def self.range_for_search(id)
    # your logic here, i.e.
    # (id-1)..(id+1)
  end
end

> Note.around_note_id(3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...