私は次の(過度に高価な)メソッドを持っています:
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