2013-05-22 31 views
0

在我的Rails应用程序,我写的是从一组记录在数据库中生成唯一的名称数组的方法:等效pluck`的`返回一个关系

class Book < ActiveRecord::Base 
    attr_accessible :title, :author 

    def self.all_authors 
    self.uniq.pluck(:author) 
    end 
end 

这种方法的工作原理预计,但这个应用程序可能最终会有大量的作者,所以现在我想在控制器中对这个查询进行分页。

class AuthorsController < ApplicationController 
    def index 
    @authors = Book.all_authors.limit(10).offset(params[:page]*10) 
    end 
end 

显然,这不起作用,因为pluck(:authors)返回一个数组,而不是一个ActiveRecord::Relation。是否有替代pluck,这将允许我使用Arel方法调用链?或者也许是一种使羽毛返回ActiveRecord::Relation而不是数组的方式?

+0

看起来。看起来像从作者那里得到这些,加入Book可能会更有意义。 –

+1

@JesseWolgamott根据当前代码,它看起来像'Book'有一个名为'authors'的列(不是关联)。也许OP可以澄清。 –

+0

你是对的;目前设置'author'的方式只是一个文本列。这可能会在未来发生变化,但现在事情就是这样。 – Ajedi32

回答

3

试试这个:

@authors = Book.limit(10).offset(params[:page]*10).all_authors 
# => ["first pair of authors", "second pair of authors", ...] 

你只需要调用pluck方法在链的末端。

否则,你可以使用select将只从数据库中返回指定的列:像你想要的所有作者(谁有一本书)的uniq的上市

@authors = Book.select(:author).limit(10).offset(params[:page]*10) 
# => [#<Book author: "first pair of authors">, #<Book author: "second pair of authors">, ...] 
+0

是的,我想到了这两种解决方案。第一种方法的问题是,all_authors是一个类方法,而不是一个范围,所以它必须在方法调用链的开始处被调用。我想我可以让它成为一个范围,但我不确定在活动记录范围中是否可以使用非抽象方法(如'pluck)。 (作用域应该返回'ActiveRecord :: Relation'对象,对吗?) – Ajedi32

+0

第二种解决方案的问题是它使'all_authors'返回一组书籍而不是作者集合,这对我来说似乎很奇怪。 – Ajedi32

+0

据此,我对在范围内使用pluck的猜测是正确的:https://github.com/rails/rails/issues/7223 我可能最终不得不去选择... – Ajedi32