2014-11-21 58 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