aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVijay Dev <vijaydev.cse@gmail.com>2012-07-21 21:50:14 +0530
committerVijay Dev <vijaydev.cse@gmail.com>2012-07-21 21:50:14 +0530
commitdad5446a6c6341f4e3f820c5cdde96db9cea0f7c (patch)
tree783c5506cd62701180838e1e6792b35397b50062
parentdb4fdb58effa7a31afc29da7a7d7fc1e1ddeff0e (diff)
parent8fe5f01c31c489548f1648b1c3269c2d1cb5e178 (diff)
downloadrails-dad5446a6c6341f4e3f820c5cdde96db9cea0f7c.tar.gz
rails-dad5446a6c6341f4e3f820c5cdde96db9cea0f7c.tar.bz2
rails-dad5446a6c6341f4e3f820c5cdde96db9cea0f7c.zip
Merge branch 'master' of github.com:lifo/docrails
-rw-r--r--activerecord/lib/active_record/null_relation.rb3
-rw-r--r--activerecord/lib/active_record/relation.rb65
-rw-r--r--activerecord/lib/active_record/relation/batches.rb12
-rw-r--r--activerecord/lib/active_record/relation/delegation.rb2
-rw-r--r--activerecord/lib/active_record/relation/merger.rb4
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb48
-rw-r--r--activerecord/lib/active_record/relation/spawn_methods.rb1
7 files changed, 108 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/null_relation.rb b/activerecord/lib/active_record/null_relation.rb
index aca8291d75..4c1c91e3df 100644
--- a/activerecord/lib/active_record/null_relation.rb
+++ b/activerecord/lib/active_record/null_relation.rb
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
module ActiveRecord
- # = Active Record Null Relation
- module NullRelation
+ module NullRelation # :nodoc:
def exec_queries
@records = []
end
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index dd1f77e925..3821c6122a 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -75,6 +75,18 @@ module ActiveRecord
binds)
end
+ # Initializes new record from relation while maintaining the current
+ # scope.
+ #
+ # Expects arguments in the same format as +Base.new+.
+ #
+ # users = User.where(name: 'DHH')
+ # user = users.new # => #<User id: nil, name: "DHH", created_at: nil, updated_at: nil>
+ #
+ # You can also pass a block to new with the new record as argument:
+ #
+ # user = users.new { |user| user.name = 'Oscar' }
+ # user.name # => Oscar
def new(*args, &block)
scoping { @klass.new(*args, &block) }
end
@@ -87,17 +99,38 @@ module ActiveRecord
alias build new
+ # Tries to create a new record with the same scoped attributes
+ # defined in the relation. Returns the initialized object if validation fails.
+ #
+ # Expects arguments in the same format as +Base.create+.
+ #
+ # ==== Examples
+ # users = User.where(name: 'Oscar')
+ # users.create # #<User id: 3, name: "oscar", ...>
+ #
+ # users.create(name: 'fxn')
+ # users.create # #<User id: 4, name: "fxn", ...>
+ #
+ # users.create { |user| user.name = 'tenderlove' }
+ # # #<User id: 5, name: "tenderlove", ...>
+ #
+ # users.create(name: nil) # validation on name
+ # # #<User id: nil, name: nil, ...>
def create(*args, &block)
scoping { @klass.create(*args, &block) }
end
+ # Similar to #create, but calls +create!+ on the base class. Raises
+ # an exception if a validation error occurs.
+ #
+ # Expects arguments in the same format as <tt>Base.create!</tt>.
def create!(*args, &block)
scoping { @klass.create!(*args, &block) }
end
# Tries to load the first record; if it fails, then <tt>create</tt> is called with the same arguments as this method.
#
- # Expects arguments in the same format as <tt>Base.create</tt>.
+ # Expects arguments in the same format as +Base.create+.
#
# ==== Examples
# # Find the first user named Penélope or create a new one.
@@ -145,12 +178,13 @@ module ActiveRecord
# are needed by the next ones when eager loading is going on.
#
# Please see further details in the
- # {Active Record Query Interface guide}[http://edgeguides.rubyonrails.org/active_record_querying.html#running-explain].
+ # {Active Record Query Interface guide}[http://guides.rubyonrails.org/active_record_querying.html#running-explain].
def explain
_, queries = collecting_queries_for_explain { exec_queries }
exec_explain(queries)
end
+ # Converts relation objects to Array.
def to_a
# We monitor here the entire execution rather than individual SELECTs
# because from the point of view of the user fetching the records of a
@@ -209,6 +243,7 @@ module ActiveRecord
c.respond_to?(:zero?) ? c.zero? : c.empty?
end
+ # Returns true if there are any records.
def any?
if block_given?
to_a.any? { |*block_args| yield(*block_args) }
@@ -217,6 +252,7 @@ module ActiveRecord
end
end
+ # Returns true if there is more than one record.
def many?
if block_given?
to_a.many? { |*block_args| yield(*block_args) }
@@ -227,8 +263,6 @@ module ActiveRecord
# Scope all queries to the current scope.
#
- # ==== Example
- #
# Comment.where(:post_id => 1).scoping do
# Comment.first # SELECT * FROM comments WHERE post_id = 1
# end
@@ -250,17 +284,14 @@ module ActiveRecord
# ==== Parameters
#
# * +updates+ - A string, array, or hash representing the SET part of an SQL statement.
- # * +conditions+ - A string, array, or hash representing the WHERE part of an SQL statement.
- # See conditions in the intro.
- # * +options+ - Additional options are <tt>:limit</tt> and <tt>:order</tt>, see the examples for usage.
#
# ==== Examples
#
# # Update all customers with the given attributes
- # Customer.update_all :wants_email => true
+ # Customer.update_all wants_email: true
#
# # Update all books with 'Rails' in their title
- # Book.where('title LIKE ?', '%Rails%').update_all(:author => 'David')
+ # Book.where('title LIKE ?', '%Rails%').update_all(author: 'David')
#
# # Update all books that match conditions, but limit it to 5 ordered by date
# Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(:author => 'David')
@@ -293,7 +324,7 @@ module ActiveRecord
# ==== Examples
#
# # Updates one record
- # Person.update(15, :user_name => 'Samuel', :group => 'expert')
+ # Person.update(15, user_name: 'Samuel', group: 'expert')
#
# # Updates multiple records
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
@@ -333,7 +364,7 @@ module ActiveRecord
# ==== Examples
#
# Person.destroy_all("last_login < '2004-04-04'")
- # Person.destroy_all(:status => "inactive")
+ # Person.destroy_all(status: "inactive")
# Person.where(:age => 0..18).destroy_all
def destroy_all(conditions = nil)
if conditions
@@ -435,6 +466,7 @@ module ActiveRecord
where(primary_key => id_or_array).delete_all
end
+ # Forces reloading of relation.
def reload
reset
to_a # force reload
@@ -448,10 +480,18 @@ module ActiveRecord
self
end
+ # Returns sql statement for the relation.
+ #
+ # Users.where(name: 'Oscar').to_sql
+ # # => SELECT "users".* FROM "users" WHERE "users"."name" = 'Oscar'
def to_sql
@to_sql ||= klass.connection.to_sql(arel, bind_values.dup)
end
+ # Returns a hash of where conditions
+ #
+ # Users.where(name: 'Oscar').where_values_hash
+ # # => {:name=>"oscar"}
def where_values_hash
equalities = with_default_scope.where_values.grep(Arel::Nodes::Equality).find_all { |node|
node.left.relation.name == table_name
@@ -469,6 +509,7 @@ module ActiveRecord
@scope_for_create ||= where_values_hash.merge(create_with_value)
end
+ # Returns true if relation needs eager loading.
def eager_loading?
@should_eager_load ||=
eager_load_values.any? ||
@@ -483,6 +524,7 @@ module ActiveRecord
includes_values & joins_values
end
+ # Compares two relations for equality.
def ==(other)
case other
when Relation
@@ -506,6 +548,7 @@ module ActiveRecord
end
end
+ # Returns true if relation is blank.
def blank?
to_a.blank?
end
diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb
index fb4388d4b2..5b78b246ab 100644
--- a/activerecord/lib/active_record/relation/batches.rb
+++ b/activerecord/lib/active_record/relation/batches.rb
@@ -9,8 +9,8 @@ module ActiveRecord
# In that case, batch processing methods allow you to work
# with the records in batches, thereby greatly reducing memory consumption.
#
- # The <tt>find_each</tt> method uses <tt>find_in_batches</tt> with a batch size of 1000 (or as
- # specified by the <tt>:batch_size</tt> option).
+ # The #find_each method uses #find_in_batches with a batch size of 1000 (or as
+ # specified by the +:batch_size+ option).
#
# Person.all.find_each do |person|
# person.do_awesome_stuff
@@ -20,7 +20,7 @@ module ActiveRecord
# person.party_all_night!
# end
#
- # You can also pass the <tt>:start</tt> option to specify
+ # You can also pass the +:start+ option to specify
# an offset to control the starting point.
def find_each(options = {})
find_in_batches(options) do |records|
@@ -29,14 +29,14 @@ module ActiveRecord
end
# Yields each batch of records that was found by the find +options+ as
- # an array. The size of each batch is set by the <tt>:batch_size</tt>
+ # an array. The size of each batch is set by the +:batch_size+
# option; the default is 1000.
#
# You can control the starting point for the batch processing by
- # supplying the <tt>:start</tt> option. This is especially useful if you
+ # supplying the +:start+ option. This is especially useful if you
# want multiple workers dealing with the same processing queue. You can
# make worker 1 handle all the records between id 0 and 10,000 and
- # worker 2 handle from 10,000 and beyond (by setting the <tt>:start</tt>
+ # worker 2 handle from 10,000 and beyond (by setting the +:start+
# option on that worker).
#
# It's not possible to set the order. That is automatically set to
diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb
index 64dda4f35a..a1c7e5b549 100644
--- a/activerecord/lib/active_record/relation/delegation.rb
+++ b/activerecord/lib/active_record/relation/delegation.rb
@@ -1,7 +1,7 @@
require 'active_support/core_ext/module/delegation'
module ActiveRecord
- module Delegation
+ module Delegation # :nodoc:
# Set up common delegations for performance (avoids method_missing)
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :to => :to_a
delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key,
diff --git a/activerecord/lib/active_record/relation/merger.rb b/activerecord/lib/active_record/relation/merger.rb
index 36f98c6480..b04dd7c6a7 100644
--- a/activerecord/lib/active_record/relation/merger.rb
+++ b/activerecord/lib/active_record/relation/merger.rb
@@ -3,7 +3,7 @@ require 'active_support/core_ext/hash/keys'
module ActiveRecord
class Relation
- class HashMerger
+ class HashMerger # :nodoc:
attr_reader :relation, :hash
def initialize(relation, hash)
@@ -28,7 +28,7 @@ module ActiveRecord
end
end
- class Merger
+ class Merger # :nodoc:
attr_reader :relation, :values
def initialize(relation, other)
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 1271b74ead..9df63d5485 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -35,7 +35,7 @@ module ActiveRecord
CODE
end
- def create_with_value
+ def create_with_value # :nodoc:
@values[:create_with] || {}
end
@@ -67,6 +67,7 @@ module ActiveRecord
args.empty? ? self : spawn.includes!(*args)
end
+ # Like #includes, but modifies the relation in place.
def includes!(*args)
args.reject! {|a| a.blank? }
@@ -84,6 +85,7 @@ module ActiveRecord
args.blank? ? self : spawn.eager_load!(*args)
end
+ # Like #eager_load, but modifies relation in place.
def eager_load!(*args)
self.eager_load_values += args
self
@@ -97,6 +99,7 @@ module ActiveRecord
args.blank? ? self : spawn.preload!(*args)
end
+ # Like #preload, but modifies relation in place.
def preload!(*args)
self.preload_values += args
self
@@ -114,6 +117,7 @@ module ActiveRecord
args.blank? ? self : spawn.references!(*args)
end
+ # Like #references, but modifies relation in place.
def references!(*args)
args.flatten!
@@ -158,6 +162,7 @@ module ActiveRecord
end
end
+ # Like #select, but modifies relation in place.
def select!(value)
self.select_values += Array.wrap(value)
self
@@ -179,6 +184,7 @@ module ActiveRecord
args.blank? ? self : spawn.group!(*args)
end
+ # Like #group, but modifies relation in place.
def group!(*args)
args.flatten!
@@ -200,6 +206,7 @@ module ActiveRecord
args.blank? ? self : spawn.order!(*args)
end
+ # Like #order, but modifies relation in place.
def order!(*args)
args.flatten!
@@ -224,6 +231,7 @@ module ActiveRecord
args.blank? ? self : spawn.reorder!(*args)
end
+ # Like #reorder, but modifies relation in place.
def reorder!(*args)
args.flatten!
@@ -240,6 +248,7 @@ module ActiveRecord
args.compact.blank? ? self : spawn.joins!(*args)
end
+ # Like #joins, but modifies relation in place.
def joins!(*args)
args.flatten!
@@ -367,6 +376,7 @@ module ActiveRecord
opts.blank? ? self : spawn.having!(opts, *rest)
end
+ # Like #having, but modifies relation in place.
def having!(opts, *rest)
references!(PredicateBuilder.references(opts)) if Hash === opts
@@ -383,6 +393,7 @@ module ActiveRecord
spawn.limit!(value)
end
+ # Like #limit, but modifies relation in place.
def limit!(value)
self.limit_value = value
self
@@ -399,6 +410,7 @@ module ActiveRecord
spawn.offset!(value)
end
+ # Like #offset, but modifies relation in place.
def offset!(value)
self.offset_value = value
self
@@ -410,6 +422,7 @@ module ActiveRecord
spawn.lock!(locks)
end
+ # Like #lock, but modifies relation in place.
def lock!(locks = true)
case locks
when String, TrueClass, NilClass
@@ -422,11 +435,11 @@ module ActiveRecord
end
# Returns a chainable relation with zero records, specifically an
- # instance of the NullRelation class.
+ # instance of the <tt>ActiveRecord::NullRelation</tt> 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 does not query the database.
+ # The returned <tt>ActiveRecord::NullRelation</tt> inherits from Relation and implements the
+ # Null Object pattern. It is an object with defined null behavior and always returns an empty
+ # array of records without quering the database.
#
# Any subsequent condition chained to the returned relation will continue
# generating an empty relation and will not fire any query to the database.
@@ -464,15 +477,34 @@ module ActiveRecord
spawn.readonly!(value)
end
+ # Like #readonly, but modifies relation in place.
def readonly!(value = true)
self.readonly_value = value
self
end
+ # Sets attributes to be used when creating new records from a
+ # relation object.
+ #
+ # users = User.where(name: 'Oscar')
+ # users.new.name # => 'Oscar'
+ #
+ # users = users.create_with(name: 'DHH')
+ # users.new.name # => 'DHH'
+ #
+ # You can pass +nil+ to +create_with+ to reset attributes:
+ #
+ # users = users.create_with(nil)
+ # users.new.name # => 'Oscar'
def create_with(value)
spawn.create_with!(value)
end
+ # Like #create_with but modifies the relation in place. Raises
+ # +ImmutableRelation+ if the relation has already been loaded.
+ #
+ # users = User.scoped.create_with!(name: 'Oscar')
+ # users.new.name # => 'Oscar'
def create_with!(value)
self.create_with_value = value ? create_with_value.merge(value) : {}
self
@@ -495,6 +527,7 @@ module ActiveRecord
spawn.from!(value, subquery_name)
end
+ # Like #from, but modifies relation in place.
def from!(value, subquery_name = nil)
self.from_value = [value, subquery_name]
self
@@ -514,6 +547,7 @@ module ActiveRecord
spawn.uniq!(value)
end
+ # Like #uniq, but modifies relation in place.
def uniq!(value = true)
self.uniq_value = value
self
@@ -563,6 +597,7 @@ module ActiveRecord
end
end
+ # Like #extending, but modifies relation in place.
def extending!(*modules, &block)
modules << Module.new(&block) if block_given?
@@ -579,15 +614,18 @@ module ActiveRecord
spawn.reverse_order!
end
+ # Like #reverse_order, but modifies relation in place.
def reverse_order!
self.reverse_order_value = !reverse_order_value
self
end
+ # Returns the Arel object associated with the relation.
def arel
@arel ||= with_default_scope.build_arel
end
+ # Like #arel, but ignores the default scope of the model.
def build_arel
arel = Arel::SelectManager.new(table.engine, table)
diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb
index 80d087a9ea..d21f02cd5f 100644
--- a/activerecord/lib/active_record/relation/spawn_methods.rb
+++ b/activerecord/lib/active_record/relation/spawn_methods.rb
@@ -34,6 +34,7 @@ module ActiveRecord
end
end
+ # Like #merge, but applies changes in place.
def merge!(other)
klass = other.is_a?(Hash) ? Relation::HashMerger : Relation::Merger
klass.new(self, other).merge