2014-11-21 59 views
0

我想知道如何通过模型属性或模型虚拟属性进行排序可以提供很多有用的功能。对从模型方法生成的虚拟属性进行排序的路径

我有一个模型叫Box有一些属性。我在我的索引视图中显示了具有属性和状态的这些框的列表。这个状态在生成之前有点特殊,并且不记录在我的数据库中(我们正在谈论实时状态,没有任何兴趣来记录它)。

我在这种状态下遇到了排序问题。

我的想法是这样的:

#Box.rb 
attr_accessor :status 

def generate_status 
    self.status = "awesome status" 
end 

def status 
    @status 
end 

def status=(val) 
    @status = val 
end 

而且我想访问这个信息我控制器上

#BoxesController.rb 
@boxes = Box.all #With my sort by virtual attribute status 

我真的不希望这样做(了解如何排序前虚拟属性):

@boxes = Box.all 
@boxes.each do |b| 
    b.status = b.generate_status 
end 

最后,如果有可能我会将其推广到所有列出的我在我的模型上通过Concern我想。但是启动这个工作,我需要知道,如果它可以通过一个虚拟的属性进行排序

编辑:

现在,我想用这种方式在一个范围:

#In a Concern included in my model 
(["status"] rescue []).each do |method| 
    scope "sort_by_#{method}", ->(order){ 
    if order.equal?("asc") 
     self.where(nil).sort!{|a,b| a.send(method) <=> b.send(method)} 
    else 
     self.where(nil).sort!{|a,b| b.send(method) <=> a.send(method)} 
    end 
    } 
end 

有没有任何错误,但我的元素没有排序。

注意,我叫["status"]暂时的,因为我目前正在试图访问该变量在我的模型中声明(其中我的关注含税)

谢谢您的帮助!

回答

0

无法使用ActiveRecord通过虚拟属性进行排序,但是,我们可以在结果上使用sort_by!http://www.ruby-doc.org/core-2.1.5/Array.html#method-i-sort_by-21

@boxes.sort_by! { |a,b| a.status <=> b.status } 

自动设置状态,你可以使用after_find回调。

#Box.rb 
attr_accessor :status 

after_find :generate_status 

def generate_status 
    self.status = 'awesome status` 
end 
+1

'sort_by' is not working。对于nil:NilClass',有'NoMethodError:未定义方法状态'的错误。但是'Box.all.map {| b | b.status}正在工作。看起来'sort_by'上的'b'变量是零。 – BriceB 2014-11-24 08:25:33

+0

您确定该数组至少包含2个项目吗? – KPheasey 2014-12-03 15:38:58