module RecordCache::ActiveRecord::UpdateAll::InstanceMethods
Public Instance Methods
__find_in_clause(sub_select)
click to toggle source
# File lib/record_cache/datastore/active_record_30.rb, line 296 def __find_in_clause(sub_select) return nil unless sub_select.arel.constraints.count == 1 constraint = sub_select.arel.constraints.first return constraint if constraint.is_a?(::Arel::Nodes::In) # directly an IN clause return nil unless constraint.respond_to?(:children) && constraint.children.count == 1 constraint = constraint.children.first return constraint if constraint.is_a?(::Arel::Nodes::In) # AND with IN clause nil end
update_all_with_record_cache(updates, conditions = nil, options = {})
click to toggle source
# File lib/record_cache/datastore/active_record_30.rb, line 306 def update_all_with_record_cache(updates, conditions = nil, options = {}) result = update_all_without_record_cache(updates, conditions, options) if record_cache? # when this condition is met, the arel.update method will be called on the current scope, see ActiveRecord::Relation#update_all unless conditions || options.present? || @limit_value.present? != @order_values.present? # get all attributes that contain a unique index for this model unique_index_attributes = RecordCache::Strategy::UniqueIndexCache.attributes(self) # go straight to SQL result (without instantiating records) for optimal performance RecordCache::Base.version_store.multi do sub_select = select(unique_index_attributes.map(&:to_s).join(',')) in_clause = __find_in_clause(sub_select) if unique_index_attributes.size == 1 && in_clause && in_clause.left.try(:name).to_s == unique_index_attributes.first.to_s # common case where the unique index is the (only) constraint on the query: SELECT id FROM people WHERE id in (...) attribute = unique_index_attributes.first in_clause.right.each do |value| record_cache.invalidate(attribute, value) end else connection.execute(sub_select.to_sql).each do |row| # invalidate the unique index for all attributes unique_index_attributes.each_with_index do |attribute, index| record_cache.invalidate(attribute, (row.is_a?(Hash) ? row[attribute.to_s] : row[index])) end end end end end end result end