当我告诉它以某种顺序显示结果时,我对RoR的行为方式有一个小问题。
我有一个名为categories的表,其中包含一个代码列。此代码列中的值包括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部分,我不能将它们视为严格整数(代码是表中的字符串类型)。
我很想知道这件事。
答案 0 :(得分:1)
boyschaser的回答呼吁:
['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',你需要在辅助方法中使用一些额外的逻辑。
答案 1 :(得分: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}
答案 2 :(得分: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