Ruby on Rails - 变更订单行为

时间:2014-02-06 16:02:37

标签: ruby-on-rails rails-activerecord

当我告诉它以某种顺序显示结果时,我对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部分,我不能将它们视为严格整数(代码是表中的字符串类型)。

我很想知道这件事。

3 个答案:

答案 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