aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record')
-rwxr-xr-xactiverecord/lib/active_record/associations.rb2
-rwxr-xr-xactiverecord/lib/active_record/base.rb102
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/abstract_adapter.rb14
-rw-r--r--activerecord/lib/active_record/connection_adapters/oci_adapter.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb10
-rw-r--r--activerecord/lib/active_record/deprecated_associations.rb8
-rw-r--r--activerecord/lib/active_record/locking.rb44
-rw-r--r--activerecord/lib/active_record/observer.rb9
-rw-r--r--activerecord/lib/active_record/timestamp.rb4
-rw-r--r--activerecord/lib/active_record/transactions.rb4
-rwxr-xr-xactiverecord/lib/active_record/validations.rb4
11 files changed, 97 insertions, 106 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index b2c30dafb3..381f3e4931 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -403,7 +403,7 @@ module ActiveRecord
#
# Adds the following methods for retrieval and query.
# +collection+ is replaced with the symbol passed as the first argument, so
- # <tt>has_and_belongs_to_many :categories</tt> would add among others +categories.empty?+.
+ # <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
# * <tt>collection(force_reload = false)</tt> - returns an array of all the associated objects.
# An empty array is returned if none is found.
# * <tt>collection<<(object, ...)</tt> - adds one or more objects to the collection by creating associations in the join table
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 0c086183dc..92f5724249 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -97,6 +97,16 @@ module ActiveRecord #:nodoc:
# end
# end
#
+ # == Accessing attributes before they have been type casted
+ #
+ # Some times you want to be able to read the raw attribute data without having the column-determined type cast run its course first.
+ # That can be done by using the <attribute>_before_type_cast accessors that all attributes have. For example, if your Account model
+ # has a balance attribute, you can call account.balance_before_type_cast or account.id_before_type_cast.
+ #
+ # This is especially useful in validation situations where the user might supply a string for an integer field and you want to display
+ # the original string back in an error message. Accessing the attribute normally would type cast the string to 0, which isn't what you
+ # want.
+ #
# == Dynamic attribute-based finders
#
# Dynamic attribute-based finders are a cleaner way of getting objects by simple queries without turning to SQL. They work by
@@ -479,20 +489,8 @@ 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 guessing rules are as follows:
- #
- # * Class name ends in "x", "ch" or "ss": "es" is appended, so a Search class becomes a searches table.
- # * Class name ends in "y" preceded by a consonant or "qu": The "y" is replaced with "ies", so a Category class becomes a categories table.
- # * Class name ends in "fe": The "fe" is replaced with "ves", so a Wife class becomes a wives table.
- # * Class name ends in "lf" or "rf": The "f" is replaced with "ves", so a Half class becomes a halves table.
- # * Class name ends in "person": The "person" is replaced with "people", so a Salesperson class becomes a salespeople table.
- # * Class name ends in "man": The "man" is replaced with "men", so a Spokesman class becomes a spokesmen table.
- # * Class name ends in "sis": The "i" is replaced with an "e", so a Basis class becomes a bases table.
- # * Class name ends in "tum" or "ium": The "um" is replaced with an "a", so a Datum class becomes a data table.
- # * Class name ends in "child": The "child" is replaced with "children", so a NodeChild class becomes a node_children table.
- # * Class name ends in an "s": No additional characters are added or removed.
- # * Class name doesn't end in "s": An "s" is appended, so a Comment class becomes a comments table.
- # * Class name with word compositions: Compositions are underscored, so CreditCard class becomes a credit_cards table.
+ # 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).
#
# Additionally, the class-level table_name_prefix is prepended to the table_name and the table_name_suffix is appended.
# So if you have "myapp_" as a prefix, the table name guess for an Account class becomes "myapp_accounts".
@@ -501,7 +499,7 @@ module ActiveRecord #:nodoc:
# "mice" table. Example:
#
# class Mouse < ActiveRecord::Base
- # def self.table_name() "mice" end
+ # table_name "mice"
# end
def table_name
table_name_prefix + undecorated_table_name(class_name_of_active_record_descendant(self)) + table_name_suffix
@@ -525,34 +523,8 @@ module ActiveRecord #:nodoc:
"type"
end
- # Defines an "attribute" method (like #inheritance_column or
- # #table_name). A new (class) method will be created with the
- # given name. If a value is specified, the new method will
- # return that value (as a string). Otherwise, the given block
- # will be used to compute the value of the method.
- #
- # The original method will be aliased, with the new name being
- # prefixed with "original_". This allows the new method to
- # access the original value.
- #
- # Example:
- #
- # class A < ActiveRecord::Base
- # define_attr_method :primary_key, "sysid"
- # define_attr_method( :inheritance_column ) do
- # original_inheritance_column + "_id"
- # end
- # end
- def define_attr_method( name, value=nil, &block )
- sing = class << self; self; end
- block = proc { value.to_s } if value
- sing.send( :alias_method, "original_#{name}", name )
- sing.send( :define_method, name, &block )
- end
-
# Sets the table name to use to the given value, or (if the value
- # is nil or false) to the value returned by the given block. (See
- # #define_attr_method).
+ # is nil or false) to the value returned by the given block.
#
# Example:
#
@@ -566,7 +538,7 @@ module ActiveRecord #:nodoc:
# Sets the name of the primary key column to use to the given value,
# or (if the value is nil or false) to the value returned by the given
- # block. (See #define_attr_method).
+ # block.
#
# Example:
#
@@ -580,7 +552,7 @@ module ActiveRecord #:nodoc:
# Sets the name of the inheritance column to use to the given value,
# or (if the value # is nil or false) to the value returned by the
- # given block. (See # #define_attr_method).
+ # given block.
#
# Example:
#
@@ -636,13 +608,14 @@ module ActiveRecord #:nodoc:
@columns = @columns_hash = @content_columns = @dynamic_methods_hash = nil
end
- def reset_column_information_and_inheritable_attributes_for_all_subclasses
+ def reset_column_information_and_inheritable_attributes_for_all_subclasses#:nodoc:
subclasses.each { |klass| klass.reset_inheritable_attributes; klass.reset_column_information }
end
# Transforms attribute key names into a more humane format, such as "First name" instead of "first_name". Example:
# Person.human_attribute_name("first_name") # => "First name"
- def human_attribute_name(attribute_key_name)
+ # Deprecated in favor of just calling "first_name".humanize
+ def human_attribute_name(attribute_key_name) #:nodoc:
attribute_key_name.humanize
end
@@ -650,12 +623,12 @@ module ActiveRecord #:nodoc:
superclass == Base || !columns_hash.has_key?(inheritance_column)
end
- def quote(object)
+ def quote(object) #:nodoc:
connection.quote(object)
end
# Used to sanitize objects before they're used in an SELECT SQL-statement. Delegates to <tt>connection.quote</tt>.
- def sanitize(object) # :nodoc:
+ def sanitize(object) #:nodoc:
connection.quote(object)
end
@@ -762,6 +735,31 @@ module ActiveRecord #:nodoc:
end
end
+ # Defines an "attribute" method (like #inheritance_column or
+ # #table_name). A new (class) method will be created with the
+ # given name. If a value is specified, the new method will
+ # return that value (as a string). Otherwise, the given block
+ # will be used to compute the value of the method.
+ #
+ # The original method will be aliased, with the new name being
+ # prefixed with "original_". This allows the new method to
+ # access the original value.
+ #
+ # Example:
+ #
+ # class A < ActiveRecord::Base
+ # define_attr_method :primary_key, "sysid"
+ # define_attr_method( :inheritance_column ) do
+ # original_inheritance_column + "_id"
+ # end
+ # end
+ def define_attr_method(name, value=nil, &block)
+ sing = class << self; self; end
+ block = proc { value.to_s } if value
+ sing.send( :alias_method, "original_#{name}", name )
+ sing.send( :define_method, name, &block )
+ end
+
protected
def subclasses
@@subclasses[self] ||= []
@@ -868,11 +866,11 @@ module ActiveRecord #:nodoc:
read_attribute(self.class.primary_key)
end
- def id_before_type_cast
+ def id_before_type_cast #:nodoc:
read_attribute_before_type_cast(self.class.primary_key)
end
- def quoted_id
+ def quoted_id #:nodoc:
quote(id, self.class.columns_hash[self.class.primary_key])
end
@@ -1123,7 +1121,7 @@ module ActiveRecord #:nodoc:
# Returns the value of attribute identified by <tt>attr_name</tt> after it has been type cast (for example,
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
- def read_attribute(attr_name) #:doc:
+ def read_attribute(attr_name)
if @attributes.keys.include? attr_name
if column = column_for_attribute(attr_name)
unserializable_attribute?(attr_name, column) ?
@@ -1162,7 +1160,7 @@ module ActiveRecord #:nodoc:
# Updates the attribute identified by <tt>attr_name</tt> with the specified +value+. Empty strings for fixnum and float
# columns are turned into nil.
- def write_attribute(attr_name, value) #:doc:
+ def write_attribute(attr_name, value)
@attributes[attr_name] = empty_string_for_number_column?(attr_name, value) ? nil : value
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 5d2c764afe..605a82bf74 100755
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -63,18 +63,6 @@ module ActiveRecord
#
# The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError
# may be returned on an error.
- #
- # == Connecting to another database for a single model
- #
- # To support different connections for different classes, you can
- # simply call establish_connection with the classes you wish to have
- # different connections for:
- #
- # class Courses < ActiveRecord::Base
- # ...
- # end
- #
- # Courses.establish_connection( ... )
def self.establish_connection(spec = nil)
case spec
when nil
@@ -151,7 +139,7 @@ module ActiveRecord
end
# Converts all strings in a hash to symbols.
- def self.symbolize_strings_in_hash(hash)
+ def self.symbolize_strings_in_hash(hash) #:nodoc:
hash.symbolize_keys
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/oci_adapter.rb b/activerecord/lib/active_record/connection_adapters/oci_adapter.rb
index 8b9b5627e0..8fb57f9c39 100644
--- a/activerecord/lib/active_record/connection_adapters/oci_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/oci_adapter.rb
@@ -215,7 +215,7 @@ begin
ConnectionAdapters::OCIAdapter.new conn, logger
end
- alias :attributes_with_quotes_pre_oci :attributes_with_quotes
+ alias :attributes_with_quotes_pre_oci :attributes_with_quotes #:nodoc:
# Enable the id column to be bound into the sql later, by the adapter's insert method.
# This is preferable to inserting the hard-coded value here, because the insert method
# needs to know the id value explicitly.
diff --git a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb
index d221f99be3..f6325d845c 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb
@@ -10,7 +10,7 @@ require 'active_record/connection_adapters/abstract_adapter'
#
module ActiveRecord
class Base
- def self.sqlserver_connection(config)
+ def self.sqlserver_connection(config) #:nodoc:
require_library_or_gem 'dbi' unless self.class.const_defined?(:DBI)
symbolize_strings_in_hash(config)
@@ -25,10 +25,6 @@ module ActiveRecord
raise ArgumentError, "No database specified. Missing argument: database."
end
- def adapter_name()
- 'SqlServer'
- end
-
conn = DBI.connect("DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};User Id=#{username};Password=#{password};")
conn["AutoCommit"] = true
@@ -295,6 +291,10 @@ EOL
end
end
+ def adapter_name()
+ 'SqlServer'
+ end
+
private
def select(sql, name = nil)
rows = []
diff --git a/activerecord/lib/active_record/deprecated_associations.rb b/activerecord/lib/active_record/deprecated_associations.rb
index 7a595eb216..a3d0f1d947 100644
--- a/activerecord/lib/active_record/deprecated_associations.rb
+++ b/activerecord/lib/active_record/deprecated_associations.rb
@@ -66,7 +66,7 @@ module ActiveRecord
end_eval
end
- def deprecated_association_comparison_method(association_name, association_class_name)
+ def deprecated_association_comparison_method(association_name, association_class_name) # :nodoc:
module_eval <<-"end_eval", __FILE__, __LINE__
def #{association_name}?(comparison_object, force_reload = false)
if comparison_object.kind_of?(#{association_class_name})
@@ -78,7 +78,7 @@ module ActiveRecord
end_eval
end
- def deprecated_has_association_method(association_name)
+ def deprecated_has_association_method(association_name) # :nodoc:
module_eval <<-"end_eval", __FILE__, __LINE__
def has_#{association_name}?(force_reload = false)
!#{association_name}(force_reload).nil?
@@ -86,7 +86,7 @@ module ActiveRecord
end_eval
end
- def deprecated_build_method(method_prefix, collection_name, collection_class_name, class_primary_key_name)
+ def deprecated_build_method(method_prefix, collection_name, collection_class_name, class_primary_key_name)# :nodoc:
module_eval <<-"end_eval", __FILE__, __LINE__
def #{method_prefix + collection_name}(attributes = {})
association = #{collection_class_name}.new
@@ -96,7 +96,7 @@ module ActiveRecord
end_eval
end
- def deprecated_create_method(method_prefix, collection_name, collection_class_name, class_primary_key_name)
+ def deprecated_create_method(method_prefix, collection_name, collection_class_name, class_primary_key_name)# :nodoc:
module_eval <<-"end_eval", __FILE__, __LINE__
def #{method_prefix + collection_name}(attributes = nil)
#{collection_class_name}.create((attributes || {}).merge({ "#{class_primary_key_name}" => id}))
diff --git a/activerecord/lib/active_record/locking.rb b/activerecord/lib/active_record/locking.rb
index e08e2fcec8..635fae89d8 100644
--- a/activerecord/lib/active_record/locking.rb
+++ b/activerecord/lib/active_record/locking.rb
@@ -1,25 +1,25 @@
module ActiveRecord
+ # Active Records support optimistic locking if the field <tt>lock_version</tt> is present. Each update to the
+ # record increments the lock_version column and the locking facilities ensure that records instantiated twice
+ # will let the last one saved raise a StaleObjectError if the first was also updated. Example:
+ #
+ # p1 = Person.find(1)
+ # p2 = Person.find(1)
+ #
+ # p1.first_name = "Michael"
+ # p1.save
+ #
+ # p2.first_name = "should fail"
+ # p2.save # Raises a ActiveRecord::StaleObjectError
+ #
+ # You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging,
+ # or otherwise apply the business logic needed to resolve the conflict.
+ #
+ # You must ensure that your database schema defaults the lock_version column to 0.
+ #
+ # This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>.
module Locking
- # Active Records support optimistic locking if the field <tt>lock_version</tt> is present. Each update to the
- # record increments the lock_version column and the locking facilities ensure that records instantiated twice
- # will let the last one saved raise a StaleObjectError if the first was also updated. Example:
- #
- # p1 = Person.find(1)
- # p2 = Person.find(1)
- #
- # p1.first_name = "Michael"
- # p1.save
- #
- # p2.first_name = "should fail"
- # p2.save # Raises a ActiveRecord::StaleObjectError
- #
- # You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging,
- # or otherwise apply the business logic needed to resolve the conflict.
- #
- # You must ensure that your database schema defaults the lock_version column to 0.
- #
- # This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>.
- def self.append_features(base)
+ def self.append_features(base) #:nodoc:
super
base.class_eval do
alias_method :update_without_lock, :update
@@ -27,7 +27,7 @@ module ActiveRecord
end
end
- def update_with_lock
+ def update_with_lock #:nodoc:
if locking_enabled?
previous_value = self.lock_version
self.lock_version = previous_value + 1
@@ -50,7 +50,7 @@ module ActiveRecord
@@lock_optimistically = true
cattr_accessor :lock_optimistically
- def locking_enabled?
+ def locking_enabled? #:nodoc:
lock_optimistically && respond_to?(:lock_version)
end
end
diff --git a/activerecord/lib/active_record/observer.rb b/activerecord/lib/active_record/observer.rb
index f08374596d..856d3fc968 100644
--- a/activerecord/lib/active_record/observer.rb
+++ b/activerecord/lib/active_record/observer.rb
@@ -21,7 +21,8 @@ module ActiveRecord
# something else than the class you're interested in observing, you can implement the observed_class class method. Like this:
#
# class AuditObserver < ActiveRecord::Observer
- # def self.observed_class() Account end
+ # observe Account
+ #
# def after_update(account)
# AuditTrail.new(account, "UPDATED")
# end
@@ -32,7 +33,8 @@ module ActiveRecord
# If the audit observer needs to watch more than one kind of object, this can be specified in an array, like this:
#
# class AuditObserver < ActiveRecord::Observer
- # def self.observed_class() [ Account, Balance ] end
+ # observe Account, Balance
+ #
# def after_update(record)
# AuditTrail.new(record, "UPDATED")
# end
@@ -44,6 +46,7 @@ module ActiveRecord
class Observer
include Singleton
+ # Attaches the observer to the supplied model classes.
def self.observe(*models)
define_method(:observed_class) { models }
end
@@ -55,7 +58,7 @@ module ActiveRecord
end
end
- def update(callback_method, object)
+ def update(callback_method, object) #:nodoc:
send(callback_method, object) if respond_to?(callback_method)
end
diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb
index 2c61f9e2d5..01a9720f52 100644
--- a/activerecord/lib/active_record/timestamp.rb
+++ b/activerecord/lib/active_record/timestamp.rb
@@ -18,7 +18,7 @@ module ActiveRecord
end
end
- def create_with_timestamps
+ def create_with_timestamps #:nodoc:
t = timestamps_gmt ? Time.now.gmtime : Time.now
write_attribute("created_at", t) if record_timestamps && respond_to?(:created_at) && created_at.nil?
write_attribute("created_on", t) if record_timestamps && respond_to?(:created_on) && created_on.nil?
@@ -29,7 +29,7 @@ module ActiveRecord
create_without_timestamps
end
- def update_with_timestamps
+ def update_with_timestamps #:nodoc:
t = timestamps_gmt ? Time.now.gmtime : Time.now
write_attribute("updated_at", t) if record_timestamps && respond_to?(:updated_at)
write_attribute("updated_on", t) if record_timestamps && respond_to?(:updated_on)
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 937955dd72..d6b99008ee 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -96,14 +96,14 @@ module ActiveRecord
end
end
- def lock_mutex
+ def lock_mutex#:nodoc:
Thread.current['open_transactions'] ||= 0
TRANSACTION_MUTEX.lock if Thread.current['open_transactions'] == 0
Thread.current['start_db_transaction'] = (Thread.current['open_transactions'] == 0)
Thread.current['open_transactions'] += 1
end
- def unlock_mutex
+ def unlock_mutex#:nodoc:
Thread.current['open_transactions'] -= 1
TRANSACTION_MUTEX.unlock if Thread.current['open_transactions'] == 0
end
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index a3cce5afa0..520ebd8458 100755
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -17,6 +17,8 @@ module ActiveRecord
:wrong_length => "is the wrong length (should be %d characters)",
:taken => "has already been taken",
}
+
+ # Holds a hash with all the default error messages, such that they can be replaced by your own copy or localizations.
cattr_accessor :default_error_messages
@@ -29,7 +31,7 @@ module ActiveRecord
end
# Adds an error message (+msg+) to the +attribute+, which will be returned on a call to <tt>on(attribute)</tt>
- # for the same attribute and ensure that this error object returns false when asked if +empty?+. More than one
+ # for the same attribute and ensure that this error object returns false when asked if <tt>empty?</tt>. More than one
# error can be added to the same +attribute+ in which case an array will be returned on a call to <tt>on(attribute)</tt>.
# If no +msg+ is supplied, "invalid" is assumed.
def add(attribute, msg = @@default_error_messages[:invalid])