2014-02-06 91 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