接下来,使用命名范围的先前记录

时间:2010-05-02 20:17:37

标签: ruby-on-rails activerecord

我有一个模型,我想要检索下一条记录和以前的记录。我想通过模型上的named_scope来做这件事,并且还作为参数传入要返回的下一个/前一个记录的X个数。

例如,假设我有5条记录:

  • 记录1
  • RECORD2
  • RECORD3
  • RECORD4
  • Record5

我希望能够调用Model.previous或Model.previous(1)来返回Record2。同样,我希望能够调用Model.next或Model.next(1)来返回Record4。作为另一个例子,我希望能够调用Model.previous(2)来返回Record3。我想你明白了。

我该如何做到这一点?

3 个答案:

答案 0 :(得分:11)

要实现类似'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

如果是这样,你可以做类似的事情:

@page = Page.find(4)
@page.previous

还有以下工作:

@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”是您要开始的记录的ID,1是您想要导航的号码。

答案 1 :(得分:0)

我添加了this feature into my gem by_star last month。它可能有一些您感兴趣的其他功能,所以check it out

您可以使用现有记录,然后在其上调用previousnext

Page.find(:last).previous

答案 2 :(得分:0)

我为任意订单条件写了一个宝石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<...>