从相关对象中获取top-x项

时间:2013-01-16 13:04:05

标签: ruby-on-rails scope rails-activerecord

我有Camping,其中有一个AuthorAuthor有许多Campings

获得“前5名”,定义为“5个最后一个阵营”,完成:

@author.campings.order(:created_at).limit(5)

但我喜欢这个概念,如果将“前5”移入露营模型,这对我来说似乎更清晰;毕竟,Camping是唯一知道top是什么的人。

这样的东西
@author.campings.top

但如何在Camping上定义此内容? @author.campings不是Camping,而是ActiveRecord::Relation。所以在 models / camping.rb 中跟随的内容不起作用:

# Scope for "top" campings
def top(amount)
  self.order("created_at").limit(amount)
end

用作

@author.top(5)

现在,我只需要在上述例子中通过关系@author获得这个“顶级”的东西。目前,“top”的定义只是“最后5个阵营”,但在下一次迭代中,根据Camping上的观看量,评级或其他参数和字段的数量,这将更加复杂。这让我相信Camping是定义“顶部”的正确位置,而不是Author

我可以将此添加到Author,但我的有限知识感觉违反了隔离模式;作者突然需要了解露营的各个领域:

# Last 5 campings for this author
def top_campings(amount)
  campings.order("created_at").limit(amount)
end

用作

@author.top_campings(5)

这种关系通常如何解决?

2 个答案:

答案 0 :(得分:2)

在Rails 3中,您可以使用scopes with arguments

class Camping < ActiveRecord::Base
  scope :top, lambda { |amount| order("created_at").limit(amount) }
end

(这与向Camping添加类方法相同,我猜两种方法都可以,所以你可以选择你喜欢的方法)

您可以按如下方式使用范围:

@author.campings.top(5)

答案 1 :(得分:1)

您希望以这种方式在您的Camping类中定义top

class Camping < ActiveRecord::Base
  def self.top(count)
    order(:created_at).limit(count)
  end
end

当您将其定义为类方法时,可以通过ActiveRecord::Relation使用,因此您可以调用@author.campings.top(5)