lib/tasks/statesman.rake in statesman-1.2.4 vs lib/tasks/statesman.rake in statesman-1.2.5
- old
+ new
@@ -23,27 +23,29 @@
transition_class.where(parent_fk => models.map(&:id)).
update_all(most_recent: nil)
end
# Set current transition's most_recent to TRUE
- ActiveRecord::Base.connection.execute %{
- UPDATE #{transition_class.table_name}
- SET most_recent = true
- FROM
- (
- SELECT initial_t.id, subsequent_t.created_at
- FROM #{transition_class.table_name} initial_t
- LEFT JOIN #{transition_class.table_name} subsequent_t ON
- (
- initial_t.#{parent_fk} = subsequent_t.#{parent_fk}
- AND initial_t.sort_key < subsequent_t.sort_key
- )
- WHERE initial_t.#{parent_fk}
- IN (#{models.map { |p| "'#{p.id}'" }.join(',')})
- AND subsequent_t.id IS NULL
- ) x
- WHERE #{transition_class.table_name}.id = x.id
- }
+ initial_t = transition_class.arel_table
+ subsequent_t = initial_t.alias
+
+ later_row_for_same_parent = initial_t[parent_fk].
+ eq(subsequent_t[parent_fk]).
+ and(initial_t[:sort_key].
+ lt(subsequent_t[:sort_key]))
+
+ no_later_row = subsequent_t[:id].eq(nil)
+ in_current_parent_batch = initial_t[parent_fk].in(models.map(&:id))
+
+ latest_ids_query = initial_t.join(subsequent_t, Arel::Nodes::OuterJoin).
+ on(later_row_for_same_parent).
+ where(no_later_row.and(in_current_parent_batch)).
+ project(initial_t[:id]).to_sql
+
+ latest_ids = transition_class.find_by_sql(latest_ids_query).
+ to_a.collect(&:id)
+
+ transition_class.where(id: latest_ids).update_all(most_recent: true)
end
done_models += batch_size
puts "Updated #{transition_class.name.pluralize} for "\
"#{[done_models, total_models].min}/#{total_models} "\