0

私は次の(過度に高価な)メソッドを持っています:

    def reorder_area_routes_by_demographics!
      self.area_routes.joins(:route).order(self.demo_criteria, :proximity_rank).readonly(false).each_with_index do |area_route, i|
        area_route.update_attributes(match_rank: i)
      end
    end

ただし、これにより、area_route ごとに UPDATE クエリが発生します。1回のクエリでこれを行う方法はありますか?

- 編集 -

Coreyward の提案による最終的な解決策:

def reorder_area_routes_by_demographics!
  sorted_ids = area_routes.joins(:route).order(self.demo_criteria, :proximity_rank).pluck(:'area_routes.id')
  AreaRoute.update_all [efficient_sort_sql(sorted_ids), *sorted_ids], {id: sorted_ids}
end

def efficient_sort_sql(sorted_ids, offset=0)
  offset.upto(offset + sorted_ids.count - 1).inject('match_rank = CASE id ') do |sql, i|
    sql << "WHEN ? THEN #{id} "
  end << 'END'
end
4

1 に答える 1