Далее, предыдущие записи с использованием именованной области - PullRequest
4 голосов
/ 03 мая 2010

У меня есть модель, для которой я хочу получить следующую запись (записи) и предыдущую запись (записи). Я хочу сделать это с помощью named_scope для модели, а также передать в качестве аргумента номер X следующих / предыдущих записей, которые нужно вернуть.

Например, допустим, у меня есть 5 записей:

  • Record1
  • Record2
  • Record3
  • Record4
  • Record5

Я хочу иметь возможность вызывать Model.previous или Model.previous (1) для возврата Record2. Точно так же я хочу иметь возможность вызывать Model.next или Model.next (1) для возврата Record4. В качестве другого примера я хочу иметь возможность вызвать Model.previous (2) для возврата Record3. Я думаю, вы поняли.

Как мне это сделать?

Ответы [ 3 ]

11 голосов
/ 03 мая 2010

Чтобы реализовать что-то вроде Model.previous, сам класс должен иметь текущее состояние. Это имело бы смысл, если бы «текущей» записью (возможно, в системе планирования публикаций?) В вашем примере была Record3, но в вашем примере это не предлагается.

Если вы хотите взять экземпляр модели и получить следующую или предыдущую запись, приведите простой пример:

class Page < ActiveRecord::Base
  def previous(offset = 0)    
    self.class.first(:conditions => ['id < ?', self.id], :limit => 1, :offset => offset, :order => "id DESC")
  end

  def next(offset = 0)
    self.class.first(:conditions => ['id > ?', self.id], :limit => 1, :offset => offset, :order => "id ASC")
  end
end

Если это так, вы можете сделать что-то вроде:

* +1007 *

Также будет работать:

@page.previous(1)
@page.next
@page.next(1)

Очевидно, это предполагает, что идея 'next' и 'previous' основана на поле 'id', которое, вероятно, не будет распространяться в течение жизни приложения.

Если вы хотите использовать это в классе, возможно, вы могли бы расширить это в именованную область, которая принимает «текущую» запись в качестве аргумента. Примерно так:

named_scope :previous, lambda { |current, offset| { :conditions => ['id < ?', current], :limit => 1, :offset => offset, :order => "id DESC" }}

Что означает, что вы можете позвонить:

Page.previous(4,1)

Где '4' - это идентификатор записи, с которой вы хотите начать, а 1 - это номер, по которому вы хотите вернуться назад.

0 голосов
/ 11 марта 2014

Я написал гем для этого при произвольных условиях заказа, order_query :

class Issue < ActiveRecord::Base
  include OrderQuery
  order_query :order_display, [
    [:priority, %w(high medium low)],
    [:valid_votes_count, :desc, sql: '(votes - suspicious_votes)'],
    [:updated_at, :desc],
    [:id, :desc]
  ]
  def valid_votes_count
    votes - suspicious_votes
  end
end

Issue.order_display         #=> ActiveRecord::Relation<...>
Issue.reverse_order_display #=> ActiveRecord::Relation<...>

# get the order object, scope default: Post.all
p = Issue.find(31).order_list(scope) #=> OrderQuery::RelativeOrder<...>
p.before         #=> ActiveRecord::Relation<...>
p.previous       #=> Issue<...>
p.position       #=> 5
p.next           #=> Issue<...>
p.after          #=> ActiveRecord::Relation<...>
0 голосов
/ 03 мая 2010

Я добавил эту функцию в свой камень by_star в прошлом месяце . Он может иметь некоторые другие функции, которые вас интересуют, поэтому проверьте его .

Это работает, если у вас есть существующая запись, а затем вызывается previous или next для этого:

Page.find(:last).previous
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...