diff options
author | Jon Leighton <j@jonathanleighton.com> | 2012-01-31 11:17:02 -0800 |
---|---|---|
committer | Jon Leighton <j@jonathanleighton.com> | 2012-01-31 11:17:02 -0800 |
commit | 75de1ce131cd39f68dbe6b68eecf2617a720a8e4 (patch) | |
tree | 93f0001a3363a1367b4412457039f3848bd57fad /activerecord/lib | |
parent | d6e41f364a73fb0378dc29d63c15ef7c18b8e18e (diff) | |
parent | 8270e4a8ce8337fca98030953922e5992b06a3dd (diff) | |
download | rails-75de1ce131cd39f68dbe6b68eecf2617a720a8e4.tar.gz rails-75de1ce131cd39f68dbe6b68eecf2617a720a8e4.tar.bz2 rails-75de1ce131cd39f68dbe6b68eecf2617a720a8e4.zip |
Merge pull request #4805 from xuanxu/none_and_null_object_pattern
Added `none` query method to return zero records.
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record.rb | 1 | ||||
-rw-r--r-- | activerecord/lib/active_record/null_relation.rb | 10 | ||||
-rw-r--r-- | activerecord/lib/active_record/querying.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/query_methods.rb | 33 |
4 files changed, 45 insertions, 1 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 78e958442f..73c8a06ab7 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -43,6 +43,7 @@ module ActiveRecord autoload :AutosaveAssociation autoload :Relation + autoload :NullRelation autoload_under 'relation' do autoload :QueryMethods diff --git a/activerecord/lib/active_record/null_relation.rb b/activerecord/lib/active_record/null_relation.rb new file mode 100644 index 0000000000..60c37ac2b7 --- /dev/null +++ b/activerecord/lib/active_record/null_relation.rb @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- + +module ActiveRecord + # = Active Record Null Relation + class NullRelation < Relation + def exec_queries + @records = [] + end + end +end
\ No newline at end of file diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb index 34ba480d83..5945b05190 100644 --- a/activerecord/lib/active_record/querying.rb +++ b/activerecord/lib/active_record/querying.rb @@ -8,7 +8,7 @@ module ActiveRecord delegate :find_each, :find_in_batches, :to => :scoped delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, - :having, :create_with, :uniq, :references, :to => :scoped + :having, :create_with, :uniq, :references, :none, :to => :scoped delegate :count, :average, :minimum, :maximum, :sum, :calculate, :pluck, :to => :scoped # Executes a custom SQL query against your database and returns all the results. The results will diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index a8ae7208fc..6a28d7b155 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -196,6 +196,39 @@ module ActiveRecord relation end + # Returns a chainable relation with zero records, specifically an + # instance of the NullRelation class. + # + # The returned NullRelation inherits from Relation and implements the + # Null Object pattern so it is an object with defined null behavior: + # it always returns an empty array of records and avoids any database query. + # + # Any subsequent condition chained to the returned relation will continue + # generating an empty relation and will not fire any query to the database. + # + # Used in cases where is needed a method or a scope that could return zero + # results but the response has to be chainable. + # + # For example: + # + # @posts = current_user.visible_posts.where(:name => params[:name]) + # # => the visible_post method response has to be a chainable Relation + # + # def visible_posts + # case role + # if 'Country Manager' + # Post.where(:country => country) + # if 'Reviewer' + # Post.published + # if 'Bad User' + # Post.none # => returning [] instead breaks the previous code + # end + # end + # + def none + NullRelation.new(@klass, @table) + end + def readonly(value = true) relation = clone relation.readonly_value = value |