将所有零值推到最后 - Ruby on Rails (Postgresql)

Push all zero values to the end - Ruby on Rails (Postgresql)

我有一个 table vehicles has_one vehicle_sizeVehicleSize 模型在 table size 中有一列,一个 String。以下是 size 值的示例:12ft, 19ft, EV。目标是根据 vehicle_sizes table.

的大小对 vehicles 进行排序

这是我目前的解决方案:

  def order_by_size(resources)
    return resources unless context.params[:by_size] == 'asc' || context.params[:by_size] == 'desc'

    if context.params[:by_size] == 'desc'
      resources.joins(:vehicle_size).group('vehicle_sizes.size').order('vehicle_sizes.size DESC')
    else
      resources.joins(:vehicle_size).group('vehicle_sizes.size').order('vehicle_sizes.size ASC')
    end
  end

上面的解决方案执行排序。但是,首先,无论顺序是 desc 还是 asc,我都需要将所有 zero 值推到最后(* 零表示 EV 或任何其他没有数字的字符串) .

我尝试使用 .sort { ... } 对记录进行排序,但 return 是 array 而不是 active relation,这对我来说是必需的。

我得到 arraysort 的解决方案:

  def order_by_size(resources)
    return resources unless context.params[:by_size] == 'asc' || context.params[:by_size] == 'desc'

    if context.params[:by_size] == 'desc'
      resources.joins(:vehicle_size).group('vehicle_sizes.size').sort do |x, y|
        if x.vehicle_size.size.to_i.zero?
          1
        elsif y.vehicle_size.size.to_i.zero?
          -1
        else
          y.vehicle_size.size.to_i <=> x.vehicle_size.size.to_i
        end
      end
    else
      resources.joins(:vehicle_size).group('vehicle_sizes.size').sort do |x, y|
        if x.vehicle_size.size.to_i.zero?
          1
        elsif y.vehicle_size.size.to_i.zero?
          -1
        else
          x.vehicle_size.size.to_i <=> y.vehicle_size.size.to_i
        end
      end
    end
  end

如何将我的第一个或第二个解决方案修改为 return 和 active relation,其中无论排序如何,所有 String(零)都将被推到最后?我在这里遗漏了什么吗?

非常感谢您考虑我的请求。

您可以在订单中添加新字段

vehicle_sizes.size = 0, vehicle_sizes.size DESC

或者

vehicle_sizes.size <> 0, vehicle_sizes.size DESC
VehicleSize.order(Arel.sql("size = 'EV', size"))

VehicleSize.order(Arel.sql("size = 'EV', size desc"))

这样 size = EV 的记录将排在最后,但其他记录将根据您的需要进行排序

结果将是关系

如果需要指定table名称,可以使用vehicle_sizes.size代替size

如果没有数字的值很少(此处为 EV 和 ED),您可以这样做以避免硬编码

zero_array = %w[EV ED]

VehicleSize.order(
  VehicleSize.sanitize_sql_for_order([Arel.sql("size IN (?), size DESC"), zero_array])
)