aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/base.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/base.rb')
-rwxr-xr-xactiverecord/lib/active_record/base.rb62
1 files changed, 35 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index a7d2b01f73..3e7fa13e97 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -40,7 +40,7 @@ module ActiveRecord #:nodoc:
class DangerousAttributeError < ActiveRecordError #:nodoc:
end
- # Raised when you've tried to access a column, which wasn't
+ # Raised when you've tried to access a column which wasn't
# loaded by your finder. Typically this is because :select
# has been specified
class MissingAttributeError < NoMethodError
@@ -72,7 +72,7 @@ module ActiveRecord #:nodoc:
# == Creation
#
# Active Records accept constructor parameters either in a hash or as a block. The hash method is especially useful when
- # you're receiving the data from somewhere else, like a HTTP request. It works like this:
+ # you're receiving the data from somewhere else, like an HTTP request. It works like this:
#
# user = User.new(:name => "David", :occupation => "Code Artist")
# user.name # => "David"
@@ -112,7 +112,7 @@ module ActiveRecord #:nodoc:
# end
#
# The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query and is thus susceptible to SQL-injection
- # attacks if the <tt>user_name</tt> and +password+ parameters come directly from a HTTP request. The <tt>authenticate_safely</tt> and
+ # attacks if the <tt>user_name</tt> and +password+ parameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and
# <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+ before inserting them in the query,
# which will ensure that an attacker can't escape the query and fake the login (or worse).
#
@@ -137,9 +137,9 @@ module ActiveRecord #:nodoc:
#
# == Overwriting default accessors
#
- # All column values are automatically available through basic accessors on the Active Record object, but some times you
- # want to specialize this behavior. This can be done by either by overwriting the default accessors (using the same
- # name as the attribute) calling read_attribute(attr_name) and write_attribute(attr_name, value) to actually change things.
+ # All column values are automatically available through basic accessors on the Active Record object, but sometimes you
+ # want to specialize this behavior. This can be done by overwriting the default accessors (using the same
+ # name as the attribute) and calling read_attribute(attr_name) and write_attribute(attr_name, value) to actually change things.
# Example:
#
# class Song < ActiveRecord::Base
@@ -230,7 +230,7 @@ module ActiveRecord #:nodoc:
#
# == Single table inheritance
#
- # Active Record allows inheritance by storing the name of the class in a column that by default is called "type" (can be changed
+ # Active Record allows inheritance by storing the name of the class in a column that by default is named "type" (can be changed
# by overwriting <tt>Base.inheritance_column</tt>). This means that an inheritance looking like this:
#
# class Company < ActiveRecord::Base; end
@@ -251,7 +251,7 @@ module ActiveRecord #:nodoc:
#
# Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection.
# All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection.
- # For example, if Course is a ActiveRecord::Base, but resides in a different database you can just say Course.establish_connection
+ # For example, if Course is an ActiveRecord::Base, but resides in a different database, you can just say Course.establish_connection
# and Course *and all its subclasses* will use this connection instead.
#
# This feature is implemented by keeping a connection pool in ActiveRecord::Base that is a Hash indexed by the class. If a connection is
@@ -260,12 +260,12 @@ module ActiveRecord #:nodoc:
# == Exceptions
#
# * +ActiveRecordError+ -- generic error class and superclass of all other errors raised by Active Record
- # * +AdapterNotSpecified+ -- the configuration hash used in <tt>establish_connection</tt> didn't include a
+ # * +AdapterNotSpecified+ -- the configuration hash used in <tt>establish_connection</tt> didn't include an
# <tt>:adapter</tt> key.
- # * +AdapterNotFound+ -- the <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified an non-existent adapter
+ # * +AdapterNotFound+ -- the <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a non-existent adapter
# (or a bad spelling of an existing one).
# * +AssociationTypeMismatch+ -- the object assigned to the association wasn't of the type specified in the association definition.
- # * +SerializationTypeMismatch+ -- the object serialized wasn't of the class specified as the second parameter.
+ # * +SerializationTypeMismatch+ -- the serialized object wasn't of the class specified as the second parameter.
# * +ConnectionNotEstablished+ -- no connection has been established. Use <tt>establish_connection</tt> before querying.
# * +RecordNotFound+ -- no record responded to the find* method.
# Either the row with the given ID doesn't exist or the row didn't meet the additional restrictions.
@@ -360,7 +360,7 @@ module ActiveRecord #:nodoc:
@@schema_format = :ruby
# Determines whether to raise an exception on mass-assignment to protected
- # attribute. Defaults to true.
+ # attributes. Defaults to true.
cattr_accessor :whiny_protected_attributes, :instance_writer => false
@@whiny_protected_attributes = true
@@ -370,10 +370,10 @@ module ActiveRecord #:nodoc:
# * Find by id: This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
# If no record can be found for all of the listed ids, then RecordNotFound will be raised.
# * Find first: This will return the first record matched by the options used. These options can either be specific
- # conditions or merely an order. If no record can matched, nil is returned.
+ # conditions or merely an order. If no record can be matched, nil is returned.
# * Find all: This will return all the records matched by the options used. If no records are found, an empty array is returned.
#
- # All approaches accept an option hash as their last parameter. The options are:
+ # All approaches accept an options hash as their last parameter. The options are:
#
# * <tt>:conditions</tt>: An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro.
# * <tt>:order</tt>: An SQL fragment like "created_at DESC, name".
@@ -384,9 +384,10 @@ module ActiveRecord #:nodoc:
# Accepts named associations in the form of :include, which will perform an INNER JOIN on the associated table(s).
# The records will be returned read-only since they will have attributes that do not correspond to the table's columns.
# Pass :readonly => false to override.
+ # See adding joins for associations under Associations.
# * <tt>:include</tt>: Names associations that should be loaded alongside using LEFT OUTER JOINs. The symbols named refer
# to already defined associations. See eager loading under Associations.
- # * <tt>:select</tt>: By default, this is * as in SELECT * FROM, but can be changed if you for example want to do a join, but not
+ # * <tt>:select</tt>: By default, this is * as in SELECT * FROM, but can be changed if you, for example, want to do a join but not
# include the joined columns.
# * <tt>:from</tt>: By default, this is the table name of the class, but can be changed to an alternate table name (or even the name
# of a database view).
@@ -398,7 +399,7 @@ module ActiveRecord #:nodoc:
# Person.find(1) # returns the object for ID = 1
# Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
# Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
- # Person.find([1]) # returns an array for objects the object with ID = 1
+ # Person.find([1]) # returns an array for the object with ID = 1
# Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC")
#
# Note that returned records may not be in the same order as the ids you
@@ -429,6 +430,13 @@ module ActiveRecord #:nodoc:
# end
def find(*args)
options = args.extract_options!
+ # Note: we extract any :joins option with a non-string value from the options, and turn it into
+ # an internal option :ar_joins. This allows code called from here to find the ar_joins, and
+ # it bypasses marking the result as read_only.
+ # A normal string join marks the result as read-only because it contains attributes from joined tables
+ # which are not in the base table and therefore prevent the result from being saved.
+ # In the case of an ar_join, the JoinDependency created to instantiate the results eliminates these
+ # bogus attributes. See JoinDependency#instantiate, and JoinBase#instantiate in associations.rb.
validate_find_options(options)
set_readonly_option!(options)
@@ -521,14 +529,14 @@ module ActiveRecord #:nodoc:
connection.update(sql, "#{name} Update")
end
- # Destroys the objects for all the records that match the +condition+ by instantiating each object and calling
+ # Destroys the objects for all the records that match the +conditions+ by instantiating each object and calling
# the destroy method. Example:
# Person.destroy_all "last_login < '2004-04-04'"
def destroy_all(conditions = nil)
find(:all, :conditions => conditions).each { |object| object.destroy }
end
- # Deletes all the records that match the +condition+ without instantiating the objects first (and hence not
+ # Deletes all the records that match the +conditions+ without instantiating the objects first (and hence not
# calling the destroy method). Example:
# Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')"
def delete_all(conditions = nil)
@@ -576,7 +584,7 @@ module ActiveRecord #:nodoc:
#
# This is used for caching aggregate values, so that they don't need to be computed every time.
# For example, a DiscussionBoard may cache post_count and comment_count otherwise every time the board is
- # shown it would have to run a SQL query to find how many posts and comments there are.
+ # shown it would have to run an SQL query to find how many posts and comments there are.
#
# ==== Options
#
@@ -687,7 +695,7 @@ module ActiveRecord #:nodoc:
# ==== Options
#
# +attr_name+ The field name that should be serialized
- # +class_name+ Optional, class name that the object should be equal to
+ # +class_name+ Optional, class name that the object type should be equal to
#
# ==== Example
# # Serialize a preferences attribute
@@ -707,7 +715,7 @@ module ActiveRecord #:nodoc:
# Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending
# directly from ActiveRecord. So if the hierarchy looks like: Reply < Message < ActiveRecord, then Message is used
# to guess the table name from even when called on Reply. The rules used to do the guess are handled by the Inflector class
- # in Active Support, which knows almost all common English inflections (report a bug if your inflection isn't covered).
+ # in Active Support, which knows almost all common English inflections. You can add new inflections in config/initializers/inflections.rb.
#
# Nested classes are given table names prefixed by the singular form of
# the parent's table name. Example:
@@ -964,7 +972,7 @@ module ActiveRecord #:nodoc:
connection.quote(value,column)
end
- # Used to sanitize objects before they're used in an SELECT SQL-statement. Delegates to <tt>connection.quote</tt>.
+ # Used to sanitize objects before they're used in an SQL SELECT statement. Delegates to <tt>connection.quote</tt>.
def sanitize(object) #:nodoc:
connection.quote(object)
end
@@ -1266,7 +1274,7 @@ module ActiveRecord #:nodoc:
# Enables dynamic finders like find_by_user_name(user_name) and find_by_user_name_and_password(user_name, password) that are turned into
# find(:first, :conditions => ["user_name = ?", user_name]) and find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password])
- # respectively. Also works for find(:all), but using find_all_by_amount(50) that are turned into find(:all, :conditions => ["amount = ?", 50]).
+ # respectively. Also works for find(:all) by using find_all_by_amount(50) that is turned into find(:all, :conditions => ["amount = ?", 50]).
#
# It's even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount
# is actually find_all_by_amount(amount, options).
@@ -1435,7 +1443,7 @@ module ActiveRecord #:nodoc:
# end
# end
#
- # You can ignore any previous scopings by using <tt>with_exclusive_scope</tt> method.
+ # You can ignore any previous scopings by using the <tt>with_exclusive_scope</tt> method.
#
# class Article < ActiveRecord::Base
# def self.find_with_exclusive_scope
@@ -1889,7 +1897,7 @@ module ActiveRecord #:nodoc:
# Allows you to set all the attributes at once by passing in a hash with keys
# matching the attribute names (which again matches the column names). Sensitive attributes can be protected
# from this form of mass-assignment by using the +attr_protected+ macro. Or you can alternatively
- # specify which attributes *can* be accessed in with the +attr_accessible+ macro. Then all the
+ # specify which attributes *can* be accessed with the +attr_accessible+ macro. Then all the
# attributes not included in that won't be allowed to be mass-assigned.
def attributes=(new_attributes, guard_protected_attributes = true)
return if new_attributes.nil?
@@ -2120,7 +2128,7 @@ module ActiveRecord #:nodoc:
default
end
- # Returns copy of the attributes hash where all the values have been safely quoted for use in
+ # Returns a copy of the attributes hash where all the values have been safely quoted for use in
# an SQL statement.
def attributes_with_quotes(include_primary_key = true, include_readonly_attributes = true)
quoted = attributes.inject({}) do |quoted, (name, value)|
@@ -2159,7 +2167,7 @@ module ActiveRecord #:nodoc:
# So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
# written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
# parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum, f for Float,
- # s for String, and a for Array. If all the values for a given attribute is empty, the attribute will be set to nil.
+ # s for String, and a for Array. If all the values for a given attribute are empty, the attribute will be set to nil.
def assign_multiparameter_attributes(pairs)
execute_callstack_for_multiparameter_attributes(
extract_callstack_for_multiparameter_attributes(pairs)