2013-10-18 59 views
1

假設我們有以下模型。按日期排序span

create_table :meetings do |t| 
    t.datetime :started_at 
    t.datetime: ended_at 
end 

class Meeting < ActiveRecord::base 
end 

我該如何訂購一個meeting_result,以便最長的會議是集合中的第一次會議,最短的會議是最後一次。

喜歡的東西

Meeting.order(longest(started_at..ended_at)) 

顯然,這是行不通的。

我該如何實現這一目標,最好不使用原始SQL?

回答

1

我不認爲你可以做到這一點,而不使用原始SQL。

使用原始SQL:

Meeting.order('(ended_at - start_at) DESC') 

(工作在PostgreSQL)

+0

似乎夠優雅。謝謝。 – Arjan

+0

不客氣@Arjan!你應該接受答案,如果它適合你的問題 – MrYoshiji

+0

是的,我刪除了接受,因爲它似乎沒有工作。但是這與默認範圍有關。再次感謝。 – Arjan

0

沒有SQL?想到兩個選項。創建一個哈希數組並在那裏排序,或者在數據庫中添加另一列並對其進行排序。

# How many records in the meetings table? This array of hashes could get huge. 
meetings_array = [] 
Meeting.all.each do |meeting| 
    meetings_array << {id: meeting.id, started_at: meeting.started_at, ended_at: meeting.ended_at , duration: meeting.ended_at - meeting.started_at } 
end 
meetings_array.sort_by { |hsh| hsh[:duration] } 

或者,創建另一列:

# Is it worth adding another column? 
create_table :meetings do |t| 
    t.datetime :started_at 
    t.datetime :ended_at 
    t.datetime :duration 
end 

更新此列,只要你有兩個started_atended_at。那麼你可以:

Meeting.order("duration") 
+0

如何將時間存儲在日期時間列中? – Arjan

+0

這對於一個簡單的命令來說太多了:第一種解決方案:您使用Ruby來計算持續時間,但SQL可以輕鬆地爲您執行;第二個解決方案:這意味着很多處理場景:對象更新,可能的零值,這是一個已存儲在2列的數據started_at&ended_at – MrYoshiji

+0

@MrYoshiji,我完全同意你:-)剛剛回答它根據約束。請注意我添加的評論。 – AdamT