aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/association_preload.rb42
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb10
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb4
-rwxr-xr-xactiverecord/lib/active_record/base.rb96
-rw-r--r--activerecord/lib/active_record/calculations.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb3
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb194
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb84
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/mysql_adapter.rb20
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb9
-rwxr-xr-xactiverecord/lib/active_record/fixtures.rb6
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb2
-rw-r--r--activerecord/lib/active_record/locking/pessimistic.rb4
-rw-r--r--activerecord/lib/active_record/migration.rb8
-rw-r--r--activerecord/lib/active_record/named_scope.rb1
-rw-r--r--activerecord/lib/active_record/reflection.rb15
-rw-r--r--activerecord/lib/active_record/serialization.rb10
-rw-r--r--activerecord/lib/active_record/serializers/json_serializer.rb8
-rw-r--r--activerecord/lib/active_record/serializers/xml_serializer.rb30
-rwxr-xr-xactiverecord/lib/active_record/validations.rb221
21 files changed, 548 insertions, 239 deletions
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb
index 7e4f7a5d4a..3e7c787dee 100644
--- a/activerecord/lib/active_record/association_preload.rb
+++ b/activerecord/lib/active_record/association_preload.rb
@@ -59,14 +59,14 @@ module ActiveRecord
def set_association_collection_records(id_to_record_map, reflection_name, associated_records, key)
associated_records.each do |associated_record|
- mapped_records = id_to_record_map[associated_record[key].to_i]
+ mapped_records = id_to_record_map[associated_record[key].to_s]
add_preloaded_records_to_collection(mapped_records, reflection_name, associated_record)
end
end
def set_association_single_records(id_to_record_map, reflection_name, associated_records, key)
associated_records.each do |associated_record|
- mapped_records = id_to_record_map[associated_record[key].to_i]
+ mapped_records = id_to_record_map[associated_record[key].to_s]
mapped_records.each do |mapped_record|
mapped_record.send("set_#{reflection_name}_target", associated_record)
end
@@ -78,16 +78,15 @@ module ActiveRecord
ids = []
records.each do |record|
ids << record.id
- mapped_records = (id_to_record_map[record.id] ||= [])
+ mapped_records = (id_to_record_map[record.id.to_s] ||= [])
mapped_records << record
end
ids.uniq!
return id_to_record_map, ids
end
- # FIXME: quoting
def preload_has_and_belongs_to_many_association(records, reflection, preload_options={})
- table_name = reflection.klass.table_name
+ table_name = reflection.klass.quoted_table_name
id_to_record_map, ids = construct_id_map(records)
records.each {|record| record.send(reflection.name).loaded}
options = reflection.options
@@ -97,7 +96,7 @@ module ActiveRecord
associated_records = reflection.klass.find(:all, :conditions => [conditions, ids],
:include => options[:include],
- :joins => "INNER JOIN #{options[:join_table]} as t0 ON #{reflection.klass.table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
+ :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} as t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
:select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as _parent_record_id",
:order => options[:order])
@@ -116,7 +115,7 @@ module ActiveRecord
source = reflection.source_reflection.name
through_records.first.class.preload_associations(through_records, source)
through_records.each do |through_record|
- add_preloaded_record_to_collection(id_to_record_map[through_record[through_primary_key].to_i],
+ add_preloaded_record_to_collection(id_to_record_map[through_record[through_primary_key].to_s],
reflection.name, through_record.send(source))
end
end
@@ -141,7 +140,7 @@ module ActiveRecord
source = reflection.source_reflection.name
through_records.first.class.preload_associations(through_records, source)
through_records.each do |through_record|
- add_preloaded_records_to_collection(id_to_record_map[through_record[through_primary_key].to_i],
+ add_preloaded_records_to_collection(id_to_record_map[through_record[through_primary_key].to_s],
reflection.name, through_record.send(source))
end
end
@@ -157,7 +156,7 @@ module ActiveRecord
if reflection.options[:source_type]
interface = reflection.source_reflection.options[:foreign_type]
- preload_options = {:conditions => ["#{interface} = ?", reflection.options[:source_type]]}
+ preload_options = {:conditions => ["#{connection.quote_column_name interface} = ?", reflection.options[:source_type]]}
records.compact!
records.first.class.preload_associations(records, through_association, preload_options)
@@ -196,18 +195,22 @@ module ActiveRecord
records.each do |record|
if klass = record.send(polymorph_type)
klass_id = record.send(primary_key_name)
-
- id_map = klasses_and_ids[klass] ||= {}
- id_list_for_klass_id = (id_map[klass_id] ||= [])
- id_list_for_klass_id << record
+ if klass_id
+ id_map = klasses_and_ids[klass] ||= {}
+ id_list_for_klass_id = (id_map[klass_id.to_s] ||= [])
+ id_list_for_klass_id << record
+ end
end
end
klasses_and_ids = klasses_and_ids.to_a
else
id_map = {}
records.each do |record|
- mapped_records = (id_map[record.send(primary_key_name)] ||= [])
- mapped_records << record
+ key = record.send(primary_key_name)
+ if key
+ mapped_records = (id_map[key.to_s] ||= [])
+ mapped_records << record
+ end
end
klasses_and_ids = [[reflection.klass.name, id_map]]
end
@@ -216,7 +219,7 @@ module ActiveRecord
klass_name, id_map = *klass_and_id
klass = klass_name.constantize
- table_name = klass.table_name
+ table_name = klass.quoted_table_name
primary_key = klass.primary_key
conditions = "#{table_name}.#{primary_key} IN (?)"
conditions << append_conditions(options, preload_options)
@@ -229,16 +232,15 @@ module ActiveRecord
end
end
- # FIXME: quoting
def find_associated_records(ids, reflection, preload_options)
options = reflection.options
- table_name = reflection.klass.table_name
+ table_name = reflection.klass.quoted_table_name
if interface = reflection.options[:as]
- conditions = "#{reflection.klass.table_name}.#{interface}_id IN (?) and #{reflection.klass.table_name}.#{interface}_type = '#{self.base_class.name.demodulize}'"
+ conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} IN (?) and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{self.base_class.name.demodulize}'"
else
foreign_key = reflection.primary_key_name
- conditions = "#{reflection.klass.table_name}.#{foreign_key} IN (?)"
+ conditions = "#{reflection.klass.quoted_table_name}.#{foreign_key} IN (?)"
end
conditions << append_conditions(options, preload_options)
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index df21124e92..c415ad2df3 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -179,6 +179,16 @@ module ActiveRecord
end
end
+ # Loads the target if needed and returns it.
+ #
+ # This method is abstract in the sense that it relies on +find_target+,
+ # which is expected to be provided by descendants.
+ #
+ # If the target is already loaded it is just returned. Thus, you can call
+ # +load_target+ unconditionally to get the target.
+ #
+ # ActiveRecord::RecordNotFound is rescued within the method, and it is
+ # not reraised. The proxy is reset and +nil+ is the return value.
def load_target
return nil unless defined?(@loaded)
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index ebea313c18..f683669615 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -10,14 +10,14 @@ module ActiveRecord
def create!(attrs = nil)
@reflection.klass.transaction do
- self << (object = @reflection.klass.send(:with_scope, :create => attrs) { @reflection.klass.create! })
+ self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.klass.create! } : @reflection.klass.create!)
object
end
end
def create(attrs = nil)
@reflection.klass.transaction do
- self << (object = @reflection.klass.send(:with_scope, :create => attrs) { @reflection.klass.create })
+ self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.klass.create } : @reflection.klass.create)
object
end
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 8bef5ed2ae..ffefc3cef3 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -11,22 +11,18 @@ module ActiveRecord #:nodoc:
class SubclassNotFound < ActiveRecordError #:nodoc:
end
- # Raised when object assigned to association is of incorrect type.
+ # Raised when an object assigned to an association has an incorrect type.
#
- # Example:
- #
- # class Ticket < ActiveRecord::Base
- # has_many :patches
- # end
- #
- # class Patch < ActiveRecord::Base
- # belongs_to :ticket
- # end
+ # class Ticket < ActiveRecord::Base
+ # has_many :patches
+ # end
#
- # and somewhere in the code:
+ # class Patch < ActiveRecord::Base
+ # belongs_to :ticket
+ # end
#
- # @ticket.patches << Comment.new(:content => "Please attach tests to your patch.")
- # @ticket.save
+ # # Comments are not patches, this assignment raises AssociationTypeMismatch.
+ # @ticket.patches << Comment.new(:content => "Please attach tests to your patch.")
class AssociationTypeMismatch < ActiveRecordError
end
@@ -59,14 +55,14 @@ module ActiveRecord #:nodoc:
class StatementInvalid < ActiveRecordError
end
- # Raised when number of bind variables in statement given to :condition key (for example, when using +find+ method)
+ # Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example, when using +find+ method)
# does not match number of expected variables.
#
- # Example:
+ # For example, in
#
- # Location.find :all, :conditions => ["lat = ? AND lng = ?", 53.7362]
+ # Location.find :all, :conditions => ["lat = ? AND lng = ?", 53.7362]
#
- # in example above two placeholders are given but only one variable to fill them.
+ # two placeholders are given but only one variable to fill them.
class PreparedStatementInvalid < ActiveRecordError
end
@@ -97,8 +93,8 @@ module ActiveRecord #:nodoc:
end
# Raised when you've tried to access a column which wasn't
- # loaded by your finder. Typically this is because :select
- # has been specified
+ # loaded by your finder. Typically this is because <tt>:select</tt>
+ # has been specified.
class MissingAttributeError < NoMethodError
end
@@ -206,7 +202,7 @@ module ActiveRecord #:nodoc:
# # Uses an integer of seconds to hold the length of the song
#
# def length=(minutes)
- # write_attribute(:length, minutes * 60)
+ # write_attribute(:length, minutes.to_i * 60)
# end
#
# def length
@@ -256,7 +252,7 @@ module ActiveRecord #:nodoc:
#
# It's even possible to use all the additional parameters to find. For example, the full interface for Payment.find_all_by_amount
# is actually Payment.find_all_by_amount(amount, options). And the full interface to Person.find_by_user_name is
- # actually Person.find_by_user_name(user_name, options). So you could call <tt>Payment.find_all_by_amount(50, :order => "created_on")</tt>.
+ # actually <tt>Person.find_by_user_name(user_name, options)</tt>. So you could call <tt>Payment.find_all_by_amount(50, :order => "created_on")</tt>.
#
# The same dynamic finder style can be used to create the object if it doesn't already exist. This dynamic finder is called with
# <tt>find_or_create_by_</tt> and will return the object if it already exists and otherwise creates it, then returns it. Protected attributes won't be set unless they are given in a block. For example:
@@ -423,7 +419,9 @@ module ActiveRecord #:nodoc:
@@default_timezone = :local
# Determines whether to use a connection for each thread, or a single shared connection for all threads.
- # Defaults to false. Set to true if you're writing a threaded application.
+ # Defaults to false. If you're writing a threaded application, set to true
+ # and periodically call verify_active_connections! to clear out connections
+ # assigned to stale threads.
cattr_accessor :allow_concurrency, :instance_writer => false
@@allow_concurrency = false
@@ -455,9 +453,9 @@ module ActiveRecord #:nodoc:
# * <tt>:limit</tt>: An integer determining the limit on the number of rows that should be returned.
# * <tt>:offset</tt>: An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.
# * <tt>:joins</tt>: Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed)
- # or named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s).
+ # or named associations in the same form used for the <tt>:include</tt> option, which will perform an INNER JOIN on the associated table(s).
# If the value is a string, then 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.
+ # Pass <tt>:readonly => false</tt> to override.
# * <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
@@ -466,7 +464,7 @@ module ActiveRecord #:nodoc:
# of a database view).
# * <tt>:readonly</tt>: Mark the returned records read-only so they cannot be saved or updated.
# * <tt>:lock</tt>: An SQL fragment like "FOR UPDATE" or "LOCK IN SHARE MODE".
- # :lock => true gives connection's default exclusive lock, usually "FOR UPDATE".
+ # <tt>:lock => true</tt> gives connection's default exclusive lock, usually "FOR UPDATE".
#
# Examples for find by id:
# Person.find(1) # returns the object for ID = 1
@@ -476,7 +474,7 @@ module ActiveRecord #:nodoc:
# 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
- # provide since database rows are unordered. Give an explicit :order
+ # provide since database rows are unordered. Give an explicit <tt>:order</tt>
# to ensure the results are sorted.
#
# Examples for find first:
@@ -532,6 +530,12 @@ module ActiveRecord #:nodoc:
find(:last, *args)
end
+ # This is an alias for find(:all). You can pass in all the same arguments to this method as you can
+ # to find(:all)
+ def all(*args)
+ find(:all, *args)
+ end
+
#
# Executes a custom sql query against your database and returns all the results. The results will
# be returned as an array with columns requested encapsulated as attributes of the model you call
@@ -595,13 +599,25 @@ module ActiveRecord #:nodoc:
# ==== Examples
# # Create a single new object
# User.create(:first_name => 'Jamie')
+ #
# # Create an Array of new objects
# User.create([{:first_name => 'Jamie'}, {:first_name => 'Jeremy'}])
- def create(attributes = nil)
+ #
+ # # Create a single object and pass it into a block to set other attributes.
+ # User.create(:first_name => 'Jamie') do |u|
+ # u.is_admin = false
+ # end
+ #
+ # # Creating an Array of new objects using a block, where the block is executed for each object:
+ # User.create([{:first_name => 'Jamie'}, {:first_name => 'Jeremy'}]) do |u|
+ # u.is_admin = false
+ # end
+ def create(attributes = nil, &block)
if attributes.is_a?(Array)
- attributes.collect { |attr| create(attr) }
+ attributes.collect { |attr| create(attr, &block) }
else
object = new(attributes)
+ yield(object) if block_given?
object.save
object
end
@@ -691,7 +707,7 @@ module ActiveRecord #:nodoc:
# +updates+ A String of column and value pairs that will be set on any records that match conditions
# +conditions+ An SQL fragment like "administrator = 1" or [ "user_name = ?", username ].
# See conditions in the intro for more info.
- # +options+ Additional options are :limit and/or :order, see the examples for usage.
+ # +options+ Additional options are <tt>:limit</tt> and/or <tt>:order</tt>, see the examples for usage.
#
# ==== Examples
#
@@ -1272,7 +1288,7 @@ module ActiveRecord #:nodoc:
private
def find_initial(options)
- options.update(:limit => 1) unless options[:include]
+ options.update(:limit => 1)
find_every(options).first
end
@@ -1501,7 +1517,7 @@ module ActiveRecord #:nodoc:
end
end
- # The optional scope argument is for the current :find scope.
+ # The optional scope argument is for the current <tt>:find</tt> scope.
def add_limit!(sql, options, scope = :auto)
scope = scope(:find) if :auto == scope
@@ -1513,15 +1529,15 @@ module ActiveRecord #:nodoc:
connection.add_limit_offset!(sql, options)
end
- # The optional scope argument is for the current :find scope.
- # The :lock option has precedence over a scoped :lock.
+ # The optional scope argument is for the current <tt>:find</tt> scope.
+ # The <tt>:lock</tt> option has precedence over a scoped <tt>:lock</tt>.
def add_lock!(sql, options, scope = :auto)
scope = scope(:find) if :auto == scope
options = options.reverse_merge(:lock => scope[:lock]) if scope
connection.add_lock!(sql, options)
end
- # The optional scope argument is for the current :find scope.
+ # The optional scope argument is for the current <tt>:find</tt> scope.
def add_joins!(sql, options, scope = :auto)
scope = scope(:find) if :auto == scope
[(scope && scope[:joins]), options[:joins]].each do |join|
@@ -1536,7 +1552,7 @@ module ActiveRecord #:nodoc:
end
# Adds a sanitized version of +conditions+ to the +sql+ string. Note that the passed-in +sql+ string is changed.
- # The optional scope argument is for the current :find scope.
+ # The optional scope argument is for the current <tt>:find</tt> scope.
def add_conditions!(sql, conditions, scope = :auto)
scope = scope(:find) if :auto == scope
conditions = [conditions]
@@ -1733,8 +1749,8 @@ module ActiveRecord #:nodoc:
protected
# Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash.
- # method_name may be :find or :create. :find parameters may include the <tt>:conditions</tt>, <tt>:joins</tt>,
- # <tt>:include</tt>, <tt>:offset</tt>, <tt>:limit</tt>, and <tt>:readonly</tt> options. :create parameters are an attributes hash.
+ # method_name may be <tt>:find</tt> or <tt>:create</tt>. <tt>:find</tt> parameters may include the <tt>:conditions</tt>, <tt>:joins</tt>,
+ # <tt>:include</tt>, <tt>:offset</tt>, <tt>:limit</tt>, and <tt>:readonly</tt> options. <tt>:create</tt> parameters are an attributes hash.
#
# class Article < ActiveRecord::Base
# def self.create_with_scope
@@ -1747,7 +1763,7 @@ module ActiveRecord #:nodoc:
# end
#
# In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of
- # :conditions and :include options in :find, which are merged.
+ # <tt>:conditions</tt> and <tt>:include</tt> options in <tt>:find</tt>, which are merged.
#
# class Article < ActiveRecord::Base
# def self.find_with_scope
@@ -2197,9 +2213,9 @@ module ActiveRecord #:nodoc:
record
end
- # Returns an instance of the specified klass with the attributes of the current record. This is mostly useful in relation to
+ # Returns an instance of the specified +klass+ with the attributes of the current record. This is mostly useful in relation to
# single-table inheritance structures where you want a subclass to appear as the superclass. This can be used along with record
- # identification in Action Pack to allow, say, Client < Company to do something like render :partial => @client.becomes(Company)
+ # identification in Action Pack to allow, say, <tt>Client < Company</tt> to do something like render <tt>:partial => @client.becomes(Company)</tt>
# to render that instance using the companies/company partial instead of clients/client.
#
# Note: The new instance will share a link to the same attributes as the original class. So any change to the attributes in either
diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb
index b5bf82ee11..3c5caefe3b 100644
--- a/activerecord/lib/active_record/calculations.rb
+++ b/activerecord/lib/active_record/calculations.rb
@@ -9,16 +9,16 @@ module ActiveRecord
# Count operates using three different approaches.
#
# * Count all: By not passing any parameters to count, it will return a count of all the rows for the model.
- # * Count using column : By passing a column name to count, it will return a count of all the rows for the model with supplied column present
+ # * Count using column: By passing a column name to count, it will return a count of all the rows for the model with supplied column present
# * Count using options will find the row count matched by the options used.
#
# The third approach, count using options, accepts an option hash as the only parameter. The options are:
#
# * <tt>:conditions</tt>: An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro.
# * <tt>:joins</tt>: Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed)
- # or named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s).
+ # or named associations in the same form used for the <tt>:include</tt> option, which will perform an INNER JOIN on the associated table(s).
# If the value is a string, then 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.
+ # Pass <tt>:readonly => false</tt> to override.
# * <tt>:include</tt>: Named associations that should be loaded alongside using LEFT OUTER JOINs. The symbols named refer
# to already defined associations. When using named associations, count returns the number of DISTINCT items for the model you're counting.
# See eager loading under Associations.
@@ -41,7 +41,7 @@ module ActiveRecord
# Person.count('id', :conditions => "age > 26") # Performs a COUNT(id)
# Person.count(:all, :conditions => "age > 26") # Performs a COUNT(*) (:all is an alias for '*')
#
- # Note: Person.count(:all) will not work because it will use :all as the condition. Use Person.count instead.
+ # Note: <tt>Person.count(:all)</tt> will not work because it will use <tt>:all</tt> as the condition. Use Person.count instead.
def count(*args)
calculate(:count, *construct_count_options_from_args(*args))
end
@@ -75,11 +75,11 @@ module ActiveRecord
end
# This calculates aggregate values in the given column. Methods for count, sum, average, minimum, and maximum have been added as shortcuts.
- # Options such as :conditions, :order, :group, :having, and :joins can be passed to customize the query.
+ # Options such as <tt>:conditions</tt>, <tt>:order</tt>, <tt>:group</tt>, <tt>:having</tt>, and <tt>:joins</tt> can be passed to customize the query.
#
# There are two basic forms of output:
# * Single aggregate value: The single value is type cast to Fixnum for COUNT, Float for AVG, and the given column's type for everything else.
- # * Grouped values: This returns an ordered hash of the values and groups them by the :group option. It takes either a column name, or the name
+ # * Grouped values: This returns an ordered hash of the values and groups them by the <tt>:group</tt> option. It takes either a column name, or the name
# of a belongs_to association.
#
# values = Person.maximum(:age, :group => 'last_name')
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
index d950181566..34627dfaf9 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
@@ -175,7 +175,7 @@ module ActiveRecord
end
# Establishes the connection to the database. Accepts a hash as input where
- # the :adapter key must be specified with the name of a database adapter (in lower-case)
+ # the <tt>:adapter</tt> key must be specified with the name of a database adapter (in lower-case)
# example for regular databases (MySQL, Postgresql, etc):
#
# ActiveRecord::Base.establish_connection(
@@ -194,6 +194,7 @@ module ActiveRecord
# )
#
# Also accepts keys as strings (for parsing from yaml for example):
+ #
# ActiveRecord::Base.establish_connection(
# "adapter" => "sqlite",
# "database" => "path/to/dbfile"
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index d30f9b4d32..d73ffc3da6 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -398,8 +398,8 @@ module ActiveRecord
# TableDefinition#timestamps that'll add created_at and updated_at as datetimes.
#
# TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
- # column if the :polymorphic option is supplied. If :polymorphic is a hash of options, these will be
- # used when creating the _type column. So what can be written like this:
+ # column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of options, these will be
+ # used when creating the <tt>_type</tt> column. So what can be written like this:
#
# create_table :taggings do |t|
# t.integer :tag_id, :tagger_id, :taggable_id
@@ -469,5 +469,195 @@ module ActiveRecord
@base.native_database_types
end
end
+
+ # Represents a SQL table in an abstract way for updating a table.
+ # Also see TableDefinition and SchemaStatements#create_table
+ #
+ # Available transformations are:
+ #
+ # change_table :table do |t|
+ # t.column
+ # t.index
+ # t.timestamps
+ # t.change
+ # t.change_default
+ # t.rename
+ # t.references
+ # t.belongs_to
+ # t.string
+ # t.text
+ # t.integer
+ # t.float
+ # t.decimal
+ # t.datetime
+ # t.timestamp
+ # t.time
+ # t.date
+ # t.binary
+ # t.boolean
+ # t.remove
+ # t.remove_references
+ # t.remove_belongs_to
+ # t.remove_index
+ # t.remove_timestamps
+ # end
+ #
+ class Table
+ def initialize(table_name, base)
+ @table_name = table_name
+ @base = base
+ end
+
+ # Adds a new column to the named table.
+ # See TableDefinition#column for details of the options you can use.
+ # ===== Examples
+ # ====== Creating a simple columns
+ # t.column(:name, :string)
+ def column(column_name, type, options = {})
+ @base.add_column(@table_name, column_name, type, options)
+ end
+
+ # Adds a new index to the table. +column_name+ can be a single Symbol, or
+ # an Array of Symbols. See SchemaStatements#add_index
+ #
+ # ===== Examples
+ # ====== Creating a simple index
+ # t.index(:name)
+ # ====== Creating a unique index
+ # t.index([:branch_id, :party_id], :unique => true)
+ # ====== Creating a named index
+ # t.index([:branch_id, :party_id], :unique => true, :name => 'by_branch_party')
+ def index(column_name, options = {})
+ @base.add_index(@table_name, column_name, options)
+ end
+
+ # Adds timestamps (created_at and updated_at) columns to the table. See SchemaStatements#timestamps
+ # ===== Examples
+ # t.timestamps
+ def timestamps
+ @base.add_timestamps(@table_name)
+ end
+
+ # Changes the column's definition according to the new options.
+ # See TableDefinition#column for details of the options you can use.
+ # ===== Examples
+ # t.change(:name, :string, :limit => 80)
+ # t.change(:description, :text)
+ def change(column_name, type, options = {})
+ @base.change_column(@table_name, column_name, type, options)
+ end
+
+ # Sets a new default value for a column. See
+ # ===== Examples
+ # t.change_default(:qualification, 'new')
+ # t.change_default(:authorized, 1)
+ def change_default(column_name, default)
+ @base.change_column_default(@table_name, column_name, default)
+ end
+
+ # Removes the column(s) from the table definition.
+ # ===== Examples
+ # t.remove(:qualification)
+ # t.remove(:qualification, :experience)
+ # t.removes(:qualification, :experience)
+ def remove(*column_names)
+ @base.remove_column(@table_name, column_names)
+ end
+
+ # Remove the given index from the table.
+ #
+ # Remove the suppliers_name_index in the suppliers table.
+ # t.remove_index :name
+ # Remove the index named accounts_branch_id_index in the accounts table.
+ # t.remove_index :column => :branch_id
+ # Remove the index named accounts_branch_id_party_id_index in the accounts table.
+ # t.remove_index :column => [:branch_id, :party_id]
+ # Remove the index named by_branch_party in the accounts table.
+ # t.remove_index :name => :by_branch_party
+ def remove_index(options = {})
+ @base.remove_index(@table_name, options)
+ end
+
+ # Removes the timestamp columns (created_at and updated_at) from the table.
+ # ===== Examples
+ # t.remove_timestamps
+ def remove_timestamps
+ @base.remove_timestamps(@table_name)
+ end
+
+ # Renames a column.
+ # ===== Example
+ # t.rename(:description, :name)
+ def rename(column_name, new_column_name)
+ @base.rename_column(@table_name, column_name, new_column_name)
+ end
+
+ # Adds a reference. Optionally adds a +type+ column. <tt>reference</tt>,
+ # <tt>references</tt> and <tt>belongs_to</tt> are all acceptable
+ # ===== Example
+ # t.references(:goat)
+ # t.references(:goat, :polymorphic => true)
+ # t.references(:goat)
+ # t.belongs_to(:goat)
+ def references(*args)
+ options = args.extract_options!
+ polymorphic = options.delete(:polymorphic)
+ args.each do |col|
+ @base.add_column(@table_name, "#{col}_id", :integer, options)
+ @base.add_column(@table_name, "#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil?
+ end
+ end
+ alias :belongs_to :references
+
+ # Adds a reference. Optionally removes a +type+ column. <tt>remove_reference</tt>,
+ # <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are all acceptable
+ # ===== Example
+ # t.remove_reference(:goat)
+ # t.remove_reference(:goat, :polymorphic => true)
+ # t.remove_references(:goat)
+ # t.remove_belongs_to(:goat)
+ def remove_references(*args)
+ options = args.extract_options!
+ polymorphic = options.delete(:polymorphic)
+ args.each do |col|
+ @base.remove_column(@table_name, "#{col}_id")
+ @base.remove_column(@table_name, "#{col}_type") unless polymorphic.nil?
+ end
+ end
+ alias :remove_belongs_to :remove_references
+
+ # Adds a column or columns of a specified type
+ # ===== Example
+ # t.string(:goat)
+ # t.string(:goat, :sheep)
+ %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
+ class_eval <<-EOV
+ def #{column_type}(*args)
+ options = args.extract_options!
+ column_names = args
+
+ column_names.each do |name|
+ column = ColumnDefinition.new(@base, name, '#{column_type}')
+ if options[:limit]
+ column.limit = options[:limit]
+ elsif native['#{column_type}'.to_sym].is_a?(Hash)
+ column.limit = native['#{column_type}'.to_sym][:limit]
+ end
+ column.precision = options[:precision]
+ column.scale = options[:scale]
+ column.default = options[:default]
+ column.null = options[:null]
+ @base.add_column(@table_name, name, column.sql_type, options)
+ end
+ end
+ EOV
+ end
+
+ private
+ def native
+ @base.native_database_types
+ end
+ end
+
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index c986f0c6f1..6aae556d67 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -45,7 +45,7 @@ module ActiveRecord
# The +options+ hash can include the following keys:
# [<tt>:id</tt>]
# Whether to automatically add a primary key column. Defaults to true.
- # Join tables for has_and_belongs_to_many should set :id => false.
+ # Join tables for +has_and_belongs_to_many+ should set <tt>:id => false</tt>.
# [<tt>:primary_key</tt>]
# The name of the primary key, if one is to be added automatically.
# Defaults to +id+.
@@ -104,6 +104,67 @@ module ActiveRecord
execute create_sql
end
+ # A block for changing columns in +table+.
+ #
+ # === Example
+ # # change_table() yields a Table instance
+ # change_table(:suppliers) do |t|
+ # t.column :name, :string, :limit => 60
+ # # Other column alterations here
+ # end
+ #
+ # ===== Examples
+ # ====== Add a column
+ # change_table(:suppliers) do |t|
+ # t.column :name, :string, :limit => 60
+ # end
+ #
+ # ====== Add 2 integer columns
+ # change_table(:suppliers) do |t|
+ # t.integer :width, :height, :null => false, :default => 0
+ # end
+ #
+ # ====== Add created_at/updated_at columns
+ # change_table(:suppliers) do |t|
+ # t.timestamps
+ # end
+ #
+ # ====== Add a foreign key column
+ # change_table(:suppliers) do |t|
+ # t.references :company
+ # end
+ #
+ # Creates a <tt>company_id(integer)</tt> column
+ #
+ # ====== Add a polymorphic foreign key column
+ # change_table(:suppliers) do |t|
+ # t.belongs_to :company, :polymorphic => true
+ # end
+ #
+ # Creates <tt>company_type(varchar)</tt> and <tt>company_id(integer)</tt> columns
+ #
+ # ====== Remove a column
+ # change_table(:suppliers) do |t|
+ # t.remove :company
+ # end
+ #
+ # ====== Remove a column
+ # change_table(:suppliers) do |t|
+ # t.remove :company_id
+ # t.remove :width, :height
+ # end
+ #
+ # ====== Remove an index
+ # change_table(:suppliers) do |t|
+ # t.remove_index :company_id
+ # end
+ #
+ # See also Table for details on
+ # all of the various column transformation
+ def change_table(table_name)
+ yield Table.new(table_name, self)
+ end
+
# Renames a table.
# ===== Example
# rename_table('octopuses', 'octopi')
@@ -124,13 +185,17 @@ module ActiveRecord
execute(add_column_sql)
end
- # Removes the column from the table definition.
+ # Removes the column(s) from the table definition.
# ===== Examples
# remove_column(:suppliers, :qualification)
- def remove_column(table_name, column_name)
- execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
+ # remove_columns(:suppliers, :qualification, :experience)
+ def remove_column(table_name, *column_names)
+ column_names.flatten.each do |column_name|
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
+ end
end
-
+ alias :remove_columns :remove_column
+
# Changes the column's definition according to the new options.
# See TableDefinition#column for details of the options you can use.
# ===== Examples
@@ -297,7 +362,14 @@ module ActiveRecord
def add_column_options!(sql, options) #:nodoc:
sql << " DEFAULT #{quote(options[:default], options[:column])}" if options_include_default?(options)
- sql << " NOT NULL" if options[:null] == false
+ # must explcitly check for :null to allow change_column to work on migrations
+ if options.has_key? :null
+ if options[:null] == false
+ sql << " NOT NULL"
+ else
+ sql << " NULL"
+ end
+ end
end
# SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 6432c3cfee..e742d60c5f 100755
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -196,7 +196,7 @@ module ActiveRecord
:primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
:string => { :name => "varchar", :limit => 255 },
:text => { :name => "text" },
- :integer => { :name => "int", :limit => 11 },
+ :integer => { :name => "int"},
:float => { :name => "float" },
:decimal => { :name => "decimal" },
:datetime => { :name => "datetime" },
@@ -365,7 +365,7 @@ module ActiveRecord
create_database(name)
end
- # Create a new MySQL database with optional :charset and :collation.
+ # Create a new MySQL database with optional <tt>:charset</tt> and <tt>:collation</tt>.
# Charset defaults to utf8.
#
# Example:
@@ -463,6 +463,22 @@ module ActiveRecord
execute "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}"
end
+ # Maps logical Rails types to MySQL-specific data types.
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
+ return super unless type.to_s == 'integer'
+
+ case limit
+ when 0..3
+ "smallint(#{limit})"
+ when 4..8
+ "int(#{limit})"
+ when 9..20
+ "bigint(#{limit})"
+ else
+ 'int(11)'
+ end
+ end
+
# SHOW VARIABLES LIKE 'name'
def show_variable(name)
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 54b50fabd8..e3f7969cdf 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -233,7 +233,7 @@ module ActiveRecord
# * <tt>:username</tt> -- Defaults to nothing
# * <tt>:password</tt> -- Defaults to nothing
# * <tt>:database</tt> -- The name of the database. No default, must be provided.
- # * <tt>:schema_search_path</tt> -- An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the :schema_order option.
+ # * <tt>:schema_search_path</tt> -- An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the <tt>:schema_order</tt> option.
# * <tt>:encoding</tt> -- An optional client encoding that is used in a SET client_encoding TO <encoding> call on the connection.
# * <tt>:min_messages</tt> -- An optional client min messages that is used in a SET client_min_messages TO <min_messages> call on the connection.
# * <tt>:allow_concurrency</tt> -- If true, use async query methods so Ruby threads don't deadlock; otherwise, use blocking query methods.
@@ -479,9 +479,9 @@ module ActiveRecord
create_database(name)
end
- # Create a new PostgreSQL database. Options include :owner, :template,
- # :encoding, :tablespace, and :connection_limit (note that MySQL uses
- # :charset while PostgreSQL uses :encoding).
+ # Create a new PostgreSQL database. Options include <tt>:owner</tt>, <tt>:template</tt>,
+ # <tt>:encoding</tt>, <tt>:tablespace</tt>, and <tt>:connection_limit</tt> (note that MySQL uses
+ # <tt>:charset</tt> while PostgreSQL uses <tt>:encoding</tt>).
#
# Example:
# create_database config[:database], config
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 59a51c0279..8fa62c1845 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -219,11 +219,14 @@ module ActiveRecord
execute "VACUUM"
end
- def remove_column(table_name, column_name) #:nodoc:
- alter_table(table_name) do |definition|
- definition.columns.delete(definition[column_name])
+ def remove_column(table_name, *column_names) #:nodoc:
+ column_names.flatten.each do |column_name|
+ alter_table(table_name) do |definition|
+ definition.columns.delete(definition[column_name])
+ end
end
end
+ alias :remove_columns :remove_column
def change_column_default(table_name, column_name, default) #:nodoc:
alter_table(table_name) do |definition|
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index f5b2e73da9..7d5fd35dae 100755
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -469,8 +469,8 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
fixtures.size > 1 ? fixtures : fixtures.first
end
- def self.cache_fixtures(connection, fixtures)
- cache_for_connection(connection).update(fixtures.index_by { |f| f.table_name })
+ def self.cache_fixtures(connection, fixtures_map)
+ cache_for_connection(connection).update(fixtures_map)
end
def self.instantiate_fixtures(object, table_name, fixtures, load_instances = true)
@@ -526,7 +526,7 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
end
end
- cache_fixtures(connection, fixtures)
+ cache_fixtures(connection, fixtures_map)
end
end
end
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index f2c2c5f070..65f88cfdc7 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -78,7 +78,7 @@ module ActiveRecord
begin
affected_rows = connection.update(<<-end_sql, "#{self.class.name} Update with optimistic locking")
- UPDATE #{self.class.table_name}
+ UPDATE #{self.class.quoted_table_name}
SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false, false, attribute_names))}
WHERE #{self.class.primary_key} = #{quote_value(id)}
AND #{self.class.quoted_locking_column} = #{quote_value(previous_value)}
diff --git a/activerecord/lib/active_record/locking/pessimistic.rb b/activerecord/lib/active_record/locking/pessimistic.rb
index caad760742..320659596f 100644
--- a/activerecord/lib/active_record/locking/pessimistic.rb
+++ b/activerecord/lib/active_record/locking/pessimistic.rb
@@ -25,12 +25,12 @@ module ActiveRecord
# Locking::Pessimistic provides support for row-level locking using
# SELECT ... FOR UPDATE and other lock types.
#
- # Pass :lock => true to ActiveRecord::Base.find to obtain an exclusive
+ # Pass <tt>:lock => true</tt> to ActiveRecord::Base.find to obtain an exclusive
# lock on the selected rows:
# # select * from accounts where id=1 for update
# Account.find(1, :lock => true)
#
- # Pass :lock => 'some locking clause' to give a database-specific locking clause
+ # Pass <tt>:lock => 'some locking clause'</tt> to give a database-specific locking clause
# of your own such as 'LOCK IN SHARE MODE' or 'FOR UPDATE NOWAIT'.
#
# Example:
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 1d63bb2f84..af4fb6e83c 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -76,16 +76,16 @@ module ActiveRecord
# * <tt>rename_table(old_name, new_name)</tt>: Renames the table called +old_name+ to +new_name+.
# * <tt>add_column(table_name, column_name, type, options)</tt>: Adds a new column to the table called +table_name+
# named +column_name+ specified to be one of the following types:
- # :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time,
- # :date, :binary, :boolean. A default value can be specified by passing an
- # +options+ hash like { :default => 11 }. Other options include :limit and :null (e.g. { :limit => 50, :null => false })
+ # <tt>:string</tt>, <tt>:text</tt>, <tt>:integer</tt>, <tt>:float</tt>, <tt>:decimal</tt>, <tt>:datetime</tt>, <tt>:timestamp</tt>, <tt>:time</tt>,
+ # <tt>:date</tt>, <tt>:binary</tt>, <tt>:boolean</tt>. A default value can be specified by passing an
+ # +options+ hash like <tt>{ :default => 11 }</tt>. Other options include <tt>:limit</tt> and <tt>:null</tt> (e.g. <tt>{ :limit => 50, :null => false }</tt>)
# -- see ActiveRecord::ConnectionAdapters::TableDefinition#column for details.
# * <tt>rename_column(table_name, column_name, new_column_name)</tt>: Renames a column but keeps the type and content.
# * <tt>change_column(table_name, column_name, type, options)</tt>: Changes the column to a different type using the same
# parameters as add_column.
# * <tt>remove_column(table_name, column_name)</tt>: Removes the column named +column_name+ from the table called +table_name+.
# * <tt>add_index(table_name, column_names, options)</tt>: Adds a new index with the name of the column. Other options include
- # :name and :unique (e.g. { :name => "users_name_index", :unique => true }).
+ # <tt>:name</tt> and <tt>:unique</tt> (e.g. <tt>{ :name => "users_name_index", :unique => true }</tt>).
# * <tt>remove_index(table_name, index_name)</tt>: Removes the index specified by +index_name+.
#
# == Irreversible transformations
diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb
index 120ec88f95..81b99f8e96 100644
--- a/activerecord/lib/active_record/named_scope.rb
+++ b/activerecord/lib/active_record/named_scope.rb
@@ -11,7 +11,6 @@ module ActiveRecord
def self.included(base)
base.class_eval do
extend ClassMethods
- named_scope :all
named_scope :scoped, lambda { |scope| scope }
end
end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 3f11133e8c..61005af83f 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -45,7 +45,7 @@ module ActiveRecord
end
# Returns an array of AssociationReflection objects for all the associations in the class. If you only want to reflect on a
- # certain association type, pass in the symbol (:has_many, :has_one, :belongs_to) for that as the first parameter.
+ # certain association type, pass in the symbol (<tt>:has_many</tt>, <tt>:has_one</tt>, <tt>:belongs_to</tt>) for that as the first parameter.
# Example:
#
# Account.reflect_on_all_associations # returns an array of all associations
@@ -90,13 +90,12 @@ module ActiveRecord
# Returns the hash of options used for the macro. For example, it would return <tt>{ :class_name => "Money" }</tt> for
# <tt>composed_of :balance, :class_name => 'Money'</tt> or +{}+ for <tt>has_many :clients</tt>.
-
def options
@options
end
- # Returns the class for the macro. For example, <tt>composed_of :balance, :class_name => 'Money'</tt> returns the +Money+
- # class and <tt>has_many :clients</tt> returns the +Client+ class.
+ # Returns the class for the macro. For example, <tt>composed_of :balance, :class_name => 'Money'</tt> returns the Money
+ # class and <tt>has_many :clients</tt> returns the Client class.
def klass
@klass ||= class_name.constantize
end
@@ -158,16 +157,16 @@ module ActiveRecord
@through_reflection ||= options[:through] ? active_record.reflect_on_association(options[:through]) : false
end
- # Gets an array of possible :through source reflection names
+ # Gets an array of possible <tt>:through</tt> source reflection names:
#
- # [singularized, pluralized]
+ # [:singularized, :pluralized]
#
def source_reflection_names
@source_reflection_names ||= (options[:source] ? [options[:source]] : [name.to_s.singularize, name]).collect { |n| n.to_sym }
end
- # Gets the source of the through reflection. It checks both a singularized and pluralized form for :belongs_to or :has_many.
- # (The :tags association on Tagging below)
+ # Gets the source of the through reflection. It checks both a singularized and pluralized form for <tt>:belongs_to</tt> or <tt>:has_many</tt>.
+ # (The <tt>:tags</tt> association on Tagging below.)
#
# class Post
# has_many :tags, :through => :taggings
diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb
index 2c8210a299..332cda1e16 100644
--- a/activerecord/lib/active_record/serialization.rb
+++ b/activerecord/lib/active_record/serialization.rb
@@ -8,11 +8,11 @@ module ActiveRecord #:nodoc:
end
# To replicate the behavior in ActiveRecord#attributes,
- # :except takes precedence over :only. If :only is not set
+ # <tt>:except</tt> takes precedence over <tt>:only</tt>. If <tt>:only</tt> is not set
# for a N level model but is set for the N+1 level models,
- # then because :except is set to a default value, the second
- # level model can have both :except and :only set. So if
- # :only is set, always delete :except.
+ # then because <tt>:except</tt> is set to a default value, the second
+ # level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if
+ # <tt>:only</tt> is set, always delete <tt>:except</tt>.
def serializable_attribute_names
attribute_names = @record.attribute_names
@@ -38,7 +38,7 @@ module ActiveRecord #:nodoc:
serializable_attribute_names + serializable_method_names
end
- # Add associations specified via the :includes option.
+ # Add associations specified via the <tt>:includes</tt> option.
# Expects a block that takes as arguments:
# +association+ - name of the association
# +records+ - the association record(s) to be serialized
diff --git a/activerecord/lib/active_record/serializers/json_serializer.rb b/activerecord/lib/active_record/serializers/json_serializer.rb
index d024adba39..419b45d475 100644
--- a/activerecord/lib/active_record/serializers/json_serializer.rb
+++ b/activerecord/lib/active_record/serializers/json_serializer.rb
@@ -16,8 +16,8 @@ module ActiveRecord #:nodoc:
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true}
#
- # The :only and :except options can be used to limit the attributes
- # included, and work similar to the #attributes method. For example:
+ # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the attributes
+ # included, and work similar to the +attributes+ method. For example:
#
# konata.to_json(:only => [ :id, :name ])
# # => {"id": 1, "name": "Konata Izumi"}
@@ -25,14 +25,14 @@ module ActiveRecord #:nodoc:
# konata.to_json(:except => [ :id, :created_at, :age ])
# # => {"name": "Konata Izumi", "awesome": true}
#
- # To include any methods on the model, use :methods.
+ # To include any methods on the model, use <tt>:methods</tt>.
#
# konata.to_json(:methods => :permalink)
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "permalink": "1-konata-izumi"}
#
- # To include associations, use :include.
+ # To include associations, use <tt>:include</tt>.
#
# konata.to_json(:include => :posts)
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb
index fbd15e06dc..2d0887ecf0 100644
--- a/activerecord/lib/active_record/serializers/xml_serializer.rb
+++ b/activerecord/lib/active_record/serializers/xml_serializer.rb
@@ -2,7 +2,7 @@ module ActiveRecord #:nodoc:
module Serialization
# Builds an XML document to represent the model. Some configuration is
# available through +options+. However more complicated cases should
- # override ActiveRecord's to_xml method.
+ # override ActiveRecord::Base#to_xml.
#
# By default the generated XML document will include the processing
# instruction and all the object's attributes. For example:
@@ -22,12 +22,12 @@ module ActiveRecord #:nodoc:
# <last-read type="date">2004-04-15</last-read>
# </topic>
#
- # This behavior can be controlled with :only, :except,
- # :skip_instruct, :skip_types and :dasherize. The :only and
- # :except options are the same as for the #attributes method.
- # The default is to dasherize all column names, to disable this,
- # set :dasherize to false. To not have the column type included
- # in the XML output, set :skip_types to true.
+ # This behavior can be controlled with <tt>:only</tt>, <tt>:except</tt>,
+ # <tt>:skip_instruct</tt>, <tt>:skip_types</tt> and <tt>:dasherize</tt>.
+ # The <tt>:only</tt> and <tt>:except</tt> options are the same as for the
+ # +attributes+ method. The default is to dasherize all column names, but you
+ # can disable this setting <tt>:dasherize</tt> to +false+. To not have the
+ # column type included in the XML output set <tt>:skip_types</tt> to +true+.
#
# For instance:
#
@@ -43,7 +43,7 @@ module ActiveRecord #:nodoc:
# <last-read type="date">2004-04-15</last-read>
# </topic>
#
- # To include first level associations use :include
+ # To include first level associations use <tt>:include</tt>:
#
# firm.to_xml :include => [ :account, :clients ]
#
@@ -98,7 +98,7 @@ module ActiveRecord #:nodoc:
# </account>
# </firm>
#
- # To include any methods on the object(s) being called use :methods
+ # To include any methods on the model being called use <tt>:methods</tt>:
#
# firm.to_xml :methods => [ :calculated_earnings, :real_earnings ]
#
@@ -108,9 +108,8 @@ module ActiveRecord #:nodoc:
# <real-earnings>5</real-earnings>
# </firm>
#
- # To call any Procs on the object(s) use :procs. The Procs
- # are passed a modified version of the options hash that was
- # given to #to_xml.
+ # To call any additional Procs use <tt>:procs</tt>. The Procs are passed a
+ # modified version of the options hash that was given to +to_xml+:
#
# proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
# firm.to_xml :procs => [ proc ]
@@ -120,7 +119,7 @@ module ActiveRecord #:nodoc:
# <abc>def</abc>
# </firm>
#
- # Alternatively, you can yield the builder object as part of the to_xml call:
+ # Alternatively, you can yield the builder object as part of the +to_xml+ call:
#
# firm.to_xml do |xml|
# xml.creator do
@@ -137,8 +136,9 @@ module ActiveRecord #:nodoc:
# </creator>
# </firm>
#
- # You can override the to_xml method in your ActiveRecord::Base
- # subclasses if you need to. The general form of doing this is:
+ # As noted above, you may override +to_xml+ in your ActiveRecord::Base
+ # subclasses to have complete control about what's generated. The general
+ # form of doing this is:
#
# class IHaveMyOwnXML < ActiveRecord::Base
# def to_xml(options = {})
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index 1d12ea8ad7..50db32725d 100755
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -201,7 +201,7 @@ module ActiveRecord
alias_method :count, :size
alias_method :length, :size
- # Return an XML representation of this error object.
+ # Returns an XML representation of this error object.
#
# class Company < ActiveRecord::Base
# validates_presence_of :name, :address, :email
@@ -266,7 +266,7 @@ module ActiveRecord
# person.attributes = { "last_name" => "Heinemeier", "phone_number" => "555-555" }
# person.save # => true (and person is now saved in the database)
#
- # An +Errors+ object is automatically created for every Active Record.
+ # An Errors object is automatically created for every Active Record.
#
# Please do have a look at ActiveRecord::Validations::ClassMethods for a higher level of validations.
module Validations
@@ -286,7 +286,7 @@ module ActiveRecord
# All of the following validations are defined in the class scope of the model that you're interested in validating.
# They offer a more declarative way of specifying when the model is valid and when it is not. It is recommended to use
- # these over the low-level calls to validate and validate_on_create when possible.
+ # these over the low-level calls to +validate+ and +validate_on_create+ when possible.
module ClassMethods
DEFAULT_VALIDATION_OPTIONS = {
:on => :save,
@@ -337,14 +337,14 @@ module ActiveRecord
# end
#
# Options:
- # * <tt>on</tt> - Specifies when this validation is active (default is :save, other options :create, :update)
- # * <tt>allow_nil</tt> - Skip validation if attribute is nil.
- # * <tt>allow_blank</tt> - Skip validation if attribute is blank.
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
+ # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
+ # * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_each(*attrs)
options = attrs.extract_options!.symbolize_keys
@@ -374,19 +374,19 @@ module ActiveRecord
#
# The added +password_confirmation+ attribute is virtual; it exists only as an in-memory attribute for validating the password.
# To achieve this, the validation adds accessors to the model for the confirmation attribute. NOTE: This check is performed
- # only if +password_confirmation+ is not nil, and by default only on save. To require confirmation, make sure to add a presence
+ # only if +password_confirmation+ is not +nil+, and by default only on save. To require confirmation, make sure to add a presence
# check for the confirmation attribute:
#
# validates_presence_of :password_confirmation, :if => :password_changed?
#
# Configuration options:
- # * <tt>message</tt> - A custom error message (default is: "doesn't match confirmation")
- # * <tt>on</tt> - Specifies when this validation is active (default is :save, other options :create, :update)
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:message</tt> - A custom error message (default is: "doesn't match confirmation").
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_confirmation_of(*attr_names)
configuration = { :message => ActiveRecord::Errors.default_error_messages[:confirmation], :on => :save }
@@ -406,21 +406,21 @@ module ActiveRecord
# validates_acceptance_of :eula, :message => "must be abided"
# end
#
- # If the database column does not exist, the terms_of_service attribute is entirely virtual. This check is
- # performed only if terms_of_service is not nil and by default on save.
+ # If the database column does not exist, the +terms_of_service+ attribute is entirely virtual. This check is
+ # performed only if +terms_of_service+ is not +nil+ and by default on save.
#
# Configuration options:
- # * <tt>message</tt> - A custom error message (default is: "must be accepted")
- # * <tt>on</tt> - Specifies when this validation is active (default is :save, other options :create, :update)
- # * <tt>allow_nil</tt> - Skip validation if attribute is nil. (default is true)
- # * <tt>accept</tt> - Specifies value that is considered accepted. The default value is a string "1", which
- # makes it easy to relate to an HTML checkbox. This should be set to 'true' if you are validating a database
- # column, since the attribute is typecast from "1" to <tt>true</tt> before validation.
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:message</tt> - A custom error message (default is: "must be accepted").
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
+ # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default is true).
+ # * <tt>:accept</tt> - Specifies value that is considered accepted. The default value is a string "1", which
+ # makes it easy to relate to an HTML checkbox. This should be set to +true+ if you are validating a database
+ # column, since the attribute is typecast from "1" to +true+ before validation.
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_acceptance_of(*attr_names)
configuration = { :message => ActiveRecord::Errors.default_error_messages[:accepted], :on => :save, :allow_nil => true, :accept => "1" }
@@ -452,8 +452,8 @@ module ActiveRecord
# This is due to the way Object#blank? handles boolean values. false.blank? # => true
#
# Configuration options:
- # * <tt>message</tt> - A custom error message (default is: "can't be blank")
- # * <tt>on</tt> - Specifies when this validation is active (default is :save, other options :create, :update)
+ # * <tt>message</tt> - A custom error message (default is: "can't be blank").
+ # * <tt>on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
# method, proc or string should return or evaluate to a true or false value.
@@ -485,24 +485,24 @@ module ActiveRecord
# end
#
# Configuration options:
- # * <tt>minimum</tt> - The minimum size of the attribute
- # * <tt>maximum</tt> - The maximum size of the attribute
- # * <tt>is</tt> - The exact size of the attribute
- # * <tt>within</tt> - A range specifying the minimum and maximum size of the attribute
- # * <tt>in</tt> - A synonym(or alias) for :within
- # * <tt>allow_nil</tt> - Attribute may be nil; skip validation.
- # * <tt>allow_blank</tt> - Attribute may be blank; skip validation.
- #
- # * <tt>too_long</tt> - The error message if the attribute goes over the maximum (default is: "is too long (maximum is %d characters)")
- # * <tt>too_short</tt> - The error message if the attribute goes under the minimum (default is: "is too short (min is %d characters)")
- # * <tt>wrong_length</tt> - The error message if using the :is method and the attribute is the wrong size (default is: "is the wrong length (should be %d characters)")
- # * <tt>message</tt> - The error message to use for a :minimum, :maximum, or :is violation. An alias of the appropriate too_long/too_short/wrong_length message
- # * <tt>on</tt> - Specifies when this validation is active (default is :save, other options :create, :update)
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:minimum</tt> - The minimum size of the attribute.
+ # * <tt>:maximum</tt> - The maximum size of the attribute.
+ # * <tt>:is</tt> - The exact size of the attribute.
+ # * <tt>:within</tt> - A range specifying the minimum and maximum size of the attribute.
+ # * <tt>:in</tt> - A synonym(or alias) for <tt>:within</tt>.
+ # * <tt>:allow_nil</tt> - Attribute may be +nil+; skip validation.
+ # * <tt>:allow_blank</tt> - Attribute may be blank; skip validation.
+ #
+ # * <tt>:too_long</tt> - The error message if the attribute goes over the maximum (default is: "is too long (maximum is %d characters)").
+ # * <tt>:too_short</tt> - The error message if the attribute goes under the minimum (default is: "is too short (min is %d characters)").
+ # * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt> method and the attribute is the wrong size (default is: "is the wrong length (should be %d characters)").
+ # * <tt>:message</tt> - The error message to use for a <tt>:minimum</tt>, <tt>:maximum</tt>, or <tt>:is</tt> violation. An alias of the appropriate <tt>too_long</tt>/<tt>too_short</tt>/<tt>wrong_length</tt> message.
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_length_of(*attrs)
# Merge given options with defaults.
@@ -584,16 +584,16 @@ module ActiveRecord
# unique index on the field. See +add_index+ for more information.
#
# Configuration options:
- # * <tt>message</tt> - Specifies a custom error message (default is: "has already been taken")
- # * <tt>scope</tt> - One or more columns by which to limit the scope of the uniqueness constraint.
- # * <tt>case_sensitive</tt> - Looks for an exact match. Ignored by non-text columns (true by default).
- # * <tt>allow_nil</tt> - If set to true, skips this validation if the attribute is null (default is: false)
- # * <tt>allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is: false)
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:message</tt> - Specifies a custom error message (default is: "has already been taken").
+ # * <tt>:scope</tt> - One or more columns by which to limit the scope of the uniqueness constraint.
+ # * <tt>:case_sensitive</tt> - Looks for an exact match. Ignored by non-text columns (+false+ by default).
+ # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
+ # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_uniqueness_of(*attr_names)
configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken], :case_sensitive => true }
@@ -669,21 +669,21 @@ module ActiveRecord
# validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create
# end
#
- # Note: use \A and \Z to match the start and end of the string, ^ and $ match the start/end of a line.
+ # Note: use <tt>\A</tt> and <tt>\Z</tt> to match the start and end of the string, <tt>^</tt> and <tt>$</tt> match the start/end of a line.
#
# A regular expression must be provided or else an exception will be raised.
#
# Configuration options:
- # * <tt>message</tt> - A custom error message (default is: "is invalid")
- # * <tt>allow_nil</tt> - If set to true, skips this validation if the attribute is null (default is: false)
- # * <tt>allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is: false)
- # * <tt>with</tt> - The regular expression used to validate the format with (note: must be supplied!)
- # * <tt>on</tt> Specifies when this validation is active (default is :save, other options :create, :update)
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:message</tt> - A custom error message (default is: "is invalid").
+ # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
+ # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
+ # * <tt>:with</tt> - The regular expression used to validate the format with (note: must be supplied!).
+ # * <tt>:on</tt> Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_format_of(*attr_names)
configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save, :with => nil }
@@ -705,15 +705,15 @@ module ActiveRecord
# end
#
# Configuration options:
- # * <tt>in</tt> - An enumerable object of available items
- # * <tt>message</tt> - Specifies a custom error message (default is: "is not included in the list")
- # * <tt>allow_nil</tt> - If set to true, skips this validation if the attribute is null (default is: false)
- # * <tt>allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is: false)
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:in</tt> - An enumerable object of available items.
+ # * <tt>:message</tt> - Specifies a custom error message (default is: "is not included in the list").
+ # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
+ # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_inclusion_of(*attr_names)
configuration = { :message => ActiveRecord::Errors.default_error_messages[:inclusion], :on => :save }
@@ -737,15 +737,15 @@ module ActiveRecord
# end
#
# Configuration options:
- # * <tt>in</tt> - An enumerable object of items that the value shouldn't be part of
- # * <tt>message</tt> - Specifies a custom error message (default is: "is reserved")
- # * <tt>allow_nil</tt> - If set to true, skips this validation if the attribute is null (default is: false)
- # * <tt>allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is: false)
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:in</tt> - An enumerable object of items that the value shouldn't be part of.
+ # * <tt>:message</tt> - Specifies a custom error message (default is: "is reserved").
+ # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
+ # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_exclusion_of(*attr_names)
configuration = { :message => ActiveRecord::Errors.default_error_messages[:exclusion], :on => :save }
@@ -777,19 +777,19 @@ module ActiveRecord
# validates_associated :book
# end
#
- # ...this would specify a circular dependency and cause infinite recursion.
+ # this would specify a circular dependency and cause infinite recursion.
#
# NOTE: This validation will not fail if the association hasn't been assigned. If you want to ensure that the association
- # is both present and guaranteed to be valid, you also need to use validates_presence_of.
+ # is both present and guaranteed to be valid, you also need to use +validates_presence_of+.
#
# Configuration options:
- # * <tt>message</tt> - A custom error message (default is: "is invalid")
- # * <tt>on</tt> Specifies when this validation is active (default is :save, other options :create, :update)
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:message</tt> - A custom error message (default is: "is invalid")
+ # * <tt>:on</tt> Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>)
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_associated(*attr_names)
configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save }
@@ -810,22 +810,22 @@ module ActiveRecord
# end
#
# Configuration options:
- # * <tt>message</tt> - A custom error message (default is: "is not a number")
- # * <tt>on</tt> Specifies when this validation is active (default is :save, other options :create, :update)
- # * <tt>only_integer</tt> Specifies whether the value has to be an integer, e.g. an integral value (default is false)
- # * <tt>allow_nil</tt> Skip validation if attribute is nil (default is false). Notice that for fixnum and float columns empty strings are converted to nil
- # * <tt>greater_than</tt> Specifies the value must be greater than the supplied value
- # * <tt>greater_than_or_equal_to</tt> Specifies the value must be greater than or equal the supplied value
- # * <tt>equal_to</tt> Specifies the value must be equal to the supplied value
- # * <tt>less_than</tt> Specifies the value must be less than the supplied value
- # * <tt>less_than_or_equal_to</tt> Specifies the value must be less than or equal the supplied value
- # * <tt>odd</tt> Specifies the value must be an odd number
- # * <tt>even</tt> Specifies the value must be an even number
- # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
- # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
+ # * <tt>:message</tt> - A custom error message (default is: "is not a number").
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
+ # * <tt>:only_integer</tt> - Specifies whether the value has to be an integer, e.g. an integral value (default is +false+).
+ # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default is +false+). Notice that for fixnum and float columns empty strings are converted to +nil+.
+ # * <tt>:greater_than</tt> - Specifies the value must be greater than the supplied value.
+ # * <tt>:greater_than_or_equal_to</tt> - Specifies the value must be greater than or equal the supplied value.
+ # * <tt>:equal_to</tt> - Specifies the value must be equal to the supplied value.
+ # * <tt>:less_than</tt> - Specifies the value must be less than the supplied value.
+ # * <tt>:less_than_or_equal_to</tt> - Specifies the value must be less than or equal the supplied value.
+ # * <tt>:odd</tt> - Specifies the value must be an odd number.
+ # * <tt>:even</tt> - Specifies the value must be an even number.
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
- # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
- # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
def validates_numericality_of(*attr_names)
configuration = { :on => :save, :only_integer => false, :allow_nil => false }
@@ -873,11 +873,12 @@ module ActiveRecord
# Creates an object just like Base.create but calls save! instead of save
# so an exception is raised if the record is invalid.
- def create!(attributes = nil)
+ def create!(attributes = nil, &block)
if attributes.is_a?(Array)
- attributes.collect { |attr| create!(attr) }
+ attributes.collect { |attr| create!(attr, &block) }
else
object = new(attributes)
+ yield(object) if block_given?
object.save!
object
end
@@ -921,7 +922,7 @@ module ActiveRecord
save(false)
end
- # Runs validate and validate_on_create or validate_on_update and returns true if no errors were added otherwise false.
+ # Runs +validate+ and +validate_on_create+ or +validate_on_update+ and returns true if no errors were added otherwise false.
def valid?
errors.clear
@@ -945,7 +946,7 @@ module ActiveRecord
end
protected
- # Overwrite this method for validation checks on all saves and use Errors.add(field, msg) for invalid attributes.
+ # Overwrite this method for validation checks on all saves and use <tt>Errors.add(field, msg)</tt> for invalid attributes.
def validate #:doc:
end