2014-04-08 27 views
1

我有一个查询将返回按照我的字段'forecast_date'订单的行,但此信息可以为null,因此在'group_by'之后,我设置了一个字符串'没有Forecast“作为没有forecast_date的行的关键。排序日期数组中的一个字符串

当我想要显示的行,我需要通过forecast_date订购,但铁轨给我一个错误:

orders.keys给我[Tue, 08 Apr 2014, 'N/A', Tue, 09 May 2013, 01 Jan 2012]

我尝试了这种方式:

@orders = Orders.where('customer_id = 9'); 
orders = @orders.group_by { | order | order.forecast_date.try(:to_date) } 

orders.keys.sort # And obtain this error 
ArgumentError: comparison of Date with String failed 

如何避免这种情况并正确排列行?

+2

请发布实际查询的代码。通过sql确定排序问题可能更容易。 – engineersmnky

+0

编辑@engineersmnky – LucasMelo

+0

您的Rails AR查询在惯例中是错误的,其中(:id => 9)将返回一个AR数组中的单个记录。 –

回答

0

您可以将一个块传递给sort方法,该方法确定如何比较数组的元素。据the documentation

The block must implement a comparison between a and b, and return -1, when a follows b, 0 when a and b are equivalent, or +1 if b follows a.

所以排序您的阵列可以是这样的:

array.sort do |a, b| 
    if a.is_a?(String) 
     1 
    elsif b.is_a?(String) 
     -1 
    else 
     a <=> b 
    end 
end 

它的工作原理,但是,我不知道这是最干净的方法在那里。

+0

你的方法解决了我的问题:),我只是减少到一行 order.keys.sort {| a,b | a.is_a?(String)|| b.is_a?(String)? -1:a <=> b} – LucasMelo

+0

还有一个问题。如果我想用字符串(customer_name)排序,我可以在我的排序中使用相同的块? – LucasMelo

+0

我编辑了我的答案,我意识到以前的版本可能会遇到一些问题,适当的排序。您可以使用它对任何日期和字符串数组进行排序,并且字符串将位于已排序数组的末尾。但是请注意,最后的字符串会相互之间随机排列,如果您想正确比较字符串,则需要实现它(如果a和b都是字符串,则可以简单使用<=>运算符)。 –

0

不知道你Orders表是什么样子,但你可以做这样的

Order.where(customer_id: 9).order("forecast_date") 

SQL

SELECT orders.* FROM orders ORDER BY forecast_date 

这东西会为了你的订单通过预测日期以零为结尾。如果你想要的东西看样订货的数量给定日期,你可以做到这一点

Order.where(customer_id: 9).order("forecast_date").group("forecast_date").select("count(id) as number_of_orders, forecast_date") 

SQL

SELECT Count(id) as number_of_orders, forecast_date FROM orders WHERE orders.customer_id = 9 GROUP BY forecast_date ORDER BY forecast_date 

这将返回与方法一个ActiveRecord :: Relation对象为forecast_datenumber_of_ordersnilforecast_date最后。

为了让您可以调用(将在年底返回日期的阵列,无),您也范畴这些

scope :by_customer,->(id){ where(customer_id: id) } 
scope :grouped_by_forecast_date,->{order("forecast_date").group("forecast_date").select("count(id) as number_of_orders, forecast_date")} 

然后就可以调用作为Order.by_customer(customer_id).grouped_by_forecast_date

日期

@orders.map(&:forecast_date)