2014-02-06 95 views
1

當我告訴它以特定順序顯示結果時,RoR的行爲方式存在一個小問題。Ruby on Rails - 更改訂單行爲

我有一個叫做包含代碼列的類別的表。此代碼列中的值包括1,6,12A和12B。當我告訴系統按順序顯示按照外鍵ID號和代碼值的結果(下拉)時,它按照1,12A,12B和6的順序列出代碼(理想情況下應該是1 ,6,12A和12B)。

這裏是下拉:

collection_select(:category, :category_id, Category.order(:award_id, :code), :id, :award_code_category) 

我知道這個問題的一部分是這兩個碼的A和B部分,我不能把他們當作嚴格的整數(代碼在一個字符串類型表)。

我很想談談這件事。

回答

1

steakchaser的回答呼籲:

['1', '12B', '12A', '6'] 

將返回

['1', '6', '12B', '12A'] 

你失去的字母排序。

您可以創建一個幫手來進行排序:

def self.sort_by_category_codes(categories) 
    sorted_categories = categories.sort do |cat1, cat2| 
    if cat1.award_id == cat2.award_id 
     # award id matches so compare by code 
     if cat1.code.to_i == cat2.code.to_i 
     # the leading numbers are the same (or no leading numbers) 
     # so compare alphabetically 
     cat1.code <=> cat2.code 
     else 
     # there was a leading number so sort numerically 
     cat1.code.to_i <=> cat2.code.to_i 
     end 
    else 
     # award ids were different so compare by them 
     cat1.award_id <=> cat2.award_id 
    end 
    end 

    return sorted_categories 
end 

兩個['1', '12A', '12B', '6']['1', '12B', '12A', '6']將返回['1', '6', '12A', '12B']

然後調用:

collection_select(:category, :category_id, sort_by_category_codes(Category.all), :id, :award_code_category) 

我有我的解決方案中看到的唯一的問題是以諸如'A'之類的字母開頭的代碼將在數字之前返回。如果你需要在'1A'之後返回'A',你將需要一些額外的輔助方法。

+0

永遠不會有一封信首先出現的情況。嗯,當我把代碼粘貼到幫助文件中,然後使用你提供的下拉代碼時,它說:未定義的方法'sort_by_category_codes'我錯過了一個明顯的步驟?在Rails 4上我應該提到。新手與幫手。 – Rachel9494

+0

我把它稱爲一般意義上的「幫手」方法。自己。」在方法名稱使其成爲類方法(靜態)之前。因此,如果該方法位於名爲Helpers的類中,那麼您可以將其稱爲Helpers.sort_by_category_codes(Category.all)。如果您有一個Category模型,則可以將該方法放在那裏並調用Category.sort_by_category_codes(Category.all) –

+0

非常感謝!我很高興我問過,我覺得我真的從這個網站學到很多東西,所以我讀的書只有很少的深度。在這裏,我學習了一些關於「自我」的問題,作爲回答我的問題的獎勵。現在下拉菜單正確排列! – Rachel9494

0

你可以使用正則表達式(最靈活取決於你真的需要找到模式)的排序中提取出來的數字部分的一部分:

['1', '12A', '12B', '6'].sort{|c1, c2| c1[/\d*(?:\.\d+)?/].to_i <=> c2[/\d*(?:\.\d+)?/].to_i} 

排序時刪除非整數也是小更易於閱讀:

['1', '12A', '12B', '6'].sort{|c1, c2| c1.delete("^0-9.").to_i <=> c2.delete("^0-9.").to_i} 
0

要排序的值的數組你會:

["1", "6", "12A", "12B"].sort do |x, y| 
    res = x.to_i <=> y.to_i 
    res = x <=> y if res == 0 
    res 
end 

要獲取的順序可以這樣做排序的類別:

categories = Category.all.sort do |x, y| 
    res = x.code.to_i <=> y.code.to_i 
    res = x.code <=> y.code if res == 0 
    res 
end 

從你的代碼,我推斷你可能要作爲排序依據award_id與第二順序排序的代碼。這將是這樣的:

categories = Category.all.sort do |x, y| 
    res = x.award_id <=> y.award_id 
    res = x.code.to_i <=> y.code.to_i if res == 0 
    res = x.code <=> y.code if res == 0 
    res 
end 
+0

我剛剛嘗試過最後一個版本,由於某種原因,它並未首先通過award_id進行排序。有了這個因素打折它可以工作,它正在按照代碼名稱正確排序。 – Rachel9494

+0

您真的想要按獎勵對象或獎勵對象的某些屬性進行排序嗎?我給出的代碼將按award_id數值進行排序,而不是根據Award的某個值。 – Coenwulf