Module: RecordCache::ActiveRecord::UpdateAll::InstanceMethods
- Defined in:
- lib/record_cache/datastore/active_record_30.rb,
lib/record_cache/datastore/active_record_31.rb,
lib/record_cache/datastore/active_record_32.rb
Instance Method Summary collapse
- #__find_in_clause(sub_select) ⇒ Object
- #update_all_with_record_cache(updates, conditions = nil, options = {}) ⇒ Object
Instance Method Details
#__find_in_clause(sub_select) ⇒ Object
297 298 299 300 301 302 303 304 305 |
# File 'lib/record_cache/datastore/active_record_30.rb', line 297 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 = {}) ⇒ Object
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/record_cache/datastore/active_record_30.rb', line 307 def update_all_with_record_cache(updates, conditions = nil, = {}) result = update_all_without_record_cache(updates, conditions, ) 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 || .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 |