2016-10-03 50 views
0

我有一個房間模型has_many間隔。間隔有一個start_date和end_date屬性。我想訂購基於以下條件的房間基於多個子模型條件/狀態排序

1-間沒有間隔 2-間任何間隔(S)與起始日期> Date.today 3-間沒有任何間隔與起始日期> Date.tody

我想以這樣的方式對房間進行排序,使房間滿足1先來,然後房間滿足2然後3使用postgresql查詢而不是模型上的方法。

雖然我找出沒有問題的,其客房使用查詢/範圍無間隔低於

joins("LEFT OUTER JOIN intervals ON rooms.id = intervals.room_id").where("intervals.id is NULL") 

我有問題,在一個查詢由3個條件訂貨,我嘗試以下

Room.joins("LEFT OUTER JOIN intervals ON rooms.id = intervals.room_id").order("CASE WHEN intervals.id IS NULL THEN 1 END ASC") 

這個查詢的問題是,如果你打電話給它不同,你會得到錯誤PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list,另一個問題,即使你在這裏調用distinct時,它可以正常工作,你將只有一個條件,這是第一個1。

我的想法是生成一個有條件的函數,根據3個條件給出生成列的值,並給出第一個值1,第二個值2和第三個值3,並按此計算值進行排序,每當我嘗試它,雖然我被上面提到的錯誤擊中。任何幫助,將不勝感激。

這是我審判所有3個條件相結合:

Room.joins("LEFT OUTER JOIN intervals ON rooms.id = intervals.room_id").group("room.id").order("CASE WHEN room.id IS NULL THEN 1 WHEN COUNT(CASE WHEN intervals.start_date > '#{Date.today.to_s(:db)}' THEN 1 END) > 0 THEN 2 WHEN COUNT(CASE WHEN intervals.start_date > '#{Date.today.to_s(:db)}' THEN 1 END) = 0 THEN 3 END") 

然而,這給出了錯誤:PG :: GroupingError:錯誤:列「intervals.id」必須出現在GROUP BY子句或使用在一個集合函數

任何幫助,將不勝感激。

回答

1

在這個「特定」情況下,我會爲您的特定業務規則取消規範模式。請記住,您可能需要在某個時候分頁,並且需要在db處進行排序。

爲此,我將一列添加到您的模型表明排序優先級:

add_column :rooms, :sort_priority, :integer, null: false, default: 0 

然後在我的模型間隔,我會包括before_save過濾器,將設置優先級

before_save -> { 
    if (start_date < blah blah blah) 
    self.priority = 1 
    elsif (blah blah) 
    etc... 
    end 
} 

然後,我會反映這在我的參考

class Room 
    has_many :intervals, -> {order :priority, :start_date} 
end 
+1

另一部分在這裏會被添加一個cronĴ ob,以確保在每天開始時更新每個房間的優先級,因爲您無法根據時間推移觸發某些事情。我相信這是完全正確的結果 – Thresh