如何重写ruby中的每个循环?

时间:2014-09-04 22:52:57

标签: ruby-on-rails ruby arrays activerecord each

我有这个循环:

  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版本相比有所不同,然后数据格式不同(数组/对象)。

有没有更好/更快的方法来重写循环版本?

4 个答案:

答案 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)