[英]How to rewrite this each loop in ruby?
我有這個循環:
stations = Station.where(...)
stations.all.each do |s|
if s.city_id == city.id
show_stations << s
end
end
這很好用,但是由於循環所有數據,我認為這有點慢。 我嘗試使用select
重寫它,如下所示:
show_stations << stations.select { |station| station.city_id == city.id}
但是與each
版本相比,保存到show_stations
數據量有所不同,因此數據的格式(數組/對象)不同。
有沒有更好/更快的方法來重寫循環版本?
最快的版本可能是用於找到關聯對象的內置rails ActiveRecord方法。
因此,只要您的Station模型包含以下內容:
class Station < ActiveRecord::Base
belongs_to :city
您的城市模型包含以下內容:
class City < ActiveRecord::Base
has_many :stations
然后,rails自動生成方法city.stations
,該方法自動從數據庫中獲取包含該城市ID的站點。 它應該是相當優化的。
如果要使其更快,則可以在遷移中將add_index :stations, :city_id
到表中,它將更快地檢索。 請注意,這僅在您有大量要搜索的電台時才節省時間。
如果需要將其設置為數組,則可以在之后使用city.stations.to_a
對其進行轉換。 並且,如果您想進一步縮小范圍,只需使用select
方法並在Station.where(...)
語句中添加之前要添加的條件。
(例如city.stations.to_a.select { |item| your_filter }
)
您還應該緩存查詢結果,例如
stations ||= Station.where("your where").where(:city_id => city.id)
Station似乎是一個活動記錄模型。 如果是這種情況,並且不需要所有站點,則可以將city.id
過濾器添加到where
語句中。
現在遇到的問題是,您要將select
返回的數組添加為show_stations
的最后一項。 如果要讓show_stations
只包含與city.id
匹配的電台, city.id
使用show_stations = ...
而不是show_stations << ...
如果希望show_stations
包含已經包含的內容以及與city.id
匹配的站點, city.id
使用show_stations + stations.select { |station| station.city_id == city.id }
show_stations + stations.select { |station| station.city_id == city.id }
。 (還有許多其他方法可以將兩個數組加在一起。)
也許您需要在where
子句中包含city參數:
stations = Station.where("your where").where(:city_id => city.id)
或相同
stations = Station.where("your where").where('city_id = ?', city.id)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.