2010-10-08 75 views
1

我正在開發一個汽車聯合應用程序,用戶可以在其中添加電梯,並且可以爲每個電梯選擇多個停靠點(通過c,d,e到A) 。現在,當用戶在數據庫中搜索電梯時,結果還應該包括諸如「A到D」,「C到B」或「C到E」等電梯。

我使用Rails 2.3.5使用下面的代碼工作,但努力把它移到Rails 3.我確信必須有一個更乾淨的方法來實現我想要做的事,並將一些代碼移動到模型。如何修改複雜的sql查詢w /加入到rails 3

如果有人能幫我解決這個問題,那將會很棒。

class Lift < ActiveRecord::Base 
    has_many :stops 
end 

class Stop < ActiveRecord::Base   
    belongs_to :lift 
    belongs_to :city 
end 

class City < ActiveRecord::Base 
    has_one :stop 
end 


@lifts = Lift.find(
    :select =>  "lifts.id, bs.city_id as start_city_id, bs2.city_id as destination_city_id", 
    :from =>  "lifts", 
    :joins =>  "LEFT JOIN stops bs ON lifts.id = bs.lift_id 
        LEFT JOIN stops bs2 ON lifts.id = bs2.lift_id 
        JOIN cities bc ON bs.city_id = bc.id 
        JOIN cities bc2 ON bs2.city_id = bc2.id", 
    :include => [:stops, :cities], 
    :conditions => "bs.lift_id = bs2.lift_id AND bs.position < bs2.position" 
        #uses the position attribute to determine the order of the stops 
) 

回答

0

我知道它是一個非常簡單的答案,但爲什麼不用這些選項在模型中創建範圍?

+0

我也想過,但我沒有任何關於如何正確處理連接的想法。也許你可以給我一些建議。 – 2010-10-08 15:05:36

0

我有點困惑,你在一起使用find的:select和include選項。我知道這樣一個事實:當你使用include時,select會被忽略(儘管有一個插件可以解決這個問題)。此外,您還包括:城市,這種關係不會出現在您的代碼中。

無論如何,如果你想一些範圍添加到您的電梯模型,我會考慮切換到阿雷爾API,這是Rails的首選方法3. http://m.onkey.org/2010/1/22/active-record-query-interface

你可以的東西,整個查詢到一個範圍(不認爲你需要:從選項 - 可能是錯誤的):

class Lift 
... 
    scope :with_all_stops, select('lifts.id, bs.city_id as start_city_id, bs2.city_id as destination_city_id').\ 
         joins('LEFT JOIN stops bs ON lifts.id = bs.lift_id ' + 
           'LEFT JOIN stops bs2 ON lifts.id = bs2.lift_id ' + 
           'JOIN cities bc ON bs.city_id = bc.id ' + 
           'JOIN cities bc2 ON bs2.city_id = bc2.id').\ 
         includes(:stops, :cities).\ 
         where('bs.lift_id = bs2.lift_id AND bs.position < bs2.position') 
... 
end 

然後,只需調用Lift.with_all_stops。或者你可以鏈接自己的條件:Lift.with_all_stops.where('cities.name =「Topeka」')。它非常強大。

如果該查詢的某些部分對自己有用(在這種情況下可疑),可以將它們分解到自己的作用域中,然後在調用時將它們鏈接在一起。或者將它們鏈接在一起另一個範圍內,然後調用它。就像我說的,Arel可以非常強大。