diff options
Diffstat (limited to 'activerecord/lib/active_record/relation.rb')
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index e4df122af6..e596df8742 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- require "arel/collectors/bind" module ActiveRecord @@ -298,6 +297,32 @@ module ActiveRecord limit_value ? to_a.many? : size > 1 end + # Returns a cache key that can be used to identify the records fetched by + # this query. The cache key is built with a fingerprint of the sql query, + # the number of records matched by the query and a timestamp of the last + # updated record. When a new record comes to match the query, or any of + # the existing records is updated or deleted, the cache key changes. + # + # Product.where("name like ?", "%Cosmic Encounter%").cache_key + # => "products/query-1850ab3d302391b85b8693e941286659-1-20150714212553907087000" + # + # If the collection is loaded, the method will iterate through the records + # to generate the timestamp, otherwise it will trigger one SQL query like: + # + # SELECT COUNT(*), MAX("products"."updated_at") FROM "products" WHERE (name like '%Cosmic Encounter%') + # + # You can also pass a custom timestamp column to fetch the timestamp of the + # last updated record. + # + # Product.where("name like ?", "%Game%").cache_key(:last_reviewed_at) + # + # You can customize the strategy to generate the key on a per model basis + # overriding ActiveRecord::Base#collection_cache_key. + def cache_key(timestamp_column = :updated_at) + @cache_keys ||= {} + @cache_keys[timestamp_column] ||= @klass.collection_cache_key(self, timestamp_column) + end + # Scope all queries to the current scope. # # Comment.where(post_id: 1).scoping do @@ -392,7 +417,7 @@ module ActiveRecord end end - # Destroys the records matching +conditions+ by instantiating each + # Destroys the records by instantiating each # record and calling its +destroy+ method. Each object's callbacks are # executed (including <tt>:dependent</tt> association options). Returns the # collection of objects that were destroyed; each will be frozen, to @@ -405,20 +430,15 @@ module ActiveRecord # rows quickly, without concern for their associations or callbacks, use # +delete_all+ instead. # - # ==== Parameters - # - # * +conditions+ - A string, array, or hash that specifies which records - # to destroy. If omitted, all records are destroyed. See the - # Conditions section in the introduction to ActiveRecord::Base for - # more information. - # # ==== Examples # - # Person.destroy_all("last_login < '2004-04-04'") - # Person.destroy_all(status: "inactive") # Person.where(age: 0..18).destroy_all def destroy_all(conditions = nil) if conditions + ActiveSupport::Deprecation.warn(<<-MESSAGE.squish) + Passing conditions to destroy_all is deprecated and will be removed in Rails 5.1. + To achieve the same use where(conditions).destroy_all + MESSAGE where(conditions).destroy_all else to_a.each(&:destroy).tap { reset } @@ -452,15 +472,13 @@ module ActiveRecord end end - # Deletes the records matching +conditions+ without instantiating the records + # Deletes the records without instantiating the records # first, and hence not calling the +destroy+ method nor invoking callbacks. This # is a single SQL DELETE statement that goes straight to the database, much more # efficient than +destroy_all+. Be careful with relations though, in particular # <tt>:dependent</tt> rules defined on associations are not honored. Returns the # number of rows affected. # - # Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')") - # Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else']) # Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all # # Both calls delete the affected posts all at once with a single DELETE statement. @@ -486,6 +504,10 @@ module ActiveRecord end if conditions + ActiveSupport::Deprecation.warn(<<-MESSAGE.squish) + Passing conditions to delete_all is deprecated and will be removed in Rails 5.1. + To achieve the same use where(conditions).delete_all + MESSAGE where(conditions).delete_all else stmt = Arel::DeleteManager.new @@ -641,6 +663,13 @@ module ActiveRecord "#<#{self.class.name} [#{entries.join(', ')}]>" end + protected + + def load_records(records) + @records = records + @loaded = true + end + private def exec_queries |