我有这个循环:
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}
但是show_stations
中保存的数据量与each
版本相比有所不同,然后数据格式不同(数组/对象)。
有没有更好/更快的方法来重写循环版本?
答案 0 :(得分:0)
Station似乎是一个活跃的记录模型。如果是这种情况,并且您不需要所有电台,则可以将city.id
过滤器添加到where
声明中。
您现在遇到的问题是,您要将select
返回的数组添加为show_stations
的最后一项。如果您希望show_stations
仅包含与city.id
匹配的电台,请使用show_stations = ...
而不是show_stations << ...
。如果您希望show_stations
包含已包含的内容以及与city.id
匹配的电台,请使用show_stations + stations.select { |station| station.city_id == city.id }
。 (a number of other approaches用于将两个数组一起添加。)
答案 1 :(得分:0)
也许您需要在where
子句中加入city参数:
stations = Station.where("your where").where(:city_id => city.id)
或相同的
stations = Station.where("your where").where('city_id = ?', city.id)
答案 2 :(得分:0)
最快的版本可能是用于查找关联对象的内置rails ActiveRecord方法。
因此,如果您的电台模型包含以下内容:
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 }
)
答案 3 :(得分:0)
您还应该缓存查询结果,如
stations ||= Station.where("your where").where(:city_id => city.id)