aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/README.rdoc4
-rw-r--r--actionmailer/lib/action_mailer/base.rb25
-rw-r--r--activemodel/lib/active_model/dirty.rb5
-rw-r--r--activerecord/lib/active_record/associations.rb2
-rw-r--r--activerecord/lib/active_record/persistence.rb15
-rw-r--r--activerecord/lib/active_record/timestamp.rb12
-rw-r--r--activesupport/lib/active_support/cache.rb93
-rw-r--r--activesupport/lib/active_support/cache/mem_cache_store.rb7
-rw-r--r--activesupport/lib/active_support/cache/memory_store.rb10
-rw-r--r--activesupport/lib/active_support/cache/strategy/local_cache.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb30
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute_accessors.rb16
-rw-r--r--activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/date/calculations.rb26
-rw-r--r--activesupport/lib/active_support/lazy_load_hooks.rb21
-rw-r--r--railties/guides/source/3_0_release_notes.textile7
-rw-r--r--railties/guides/source/active_support_core_extensions.textile15
-rw-r--r--railties/guides/source/configuring.textile2
-rw-r--r--railties/guides/source/contributing_to_rails.textile25
-rw-r--r--railties/guides/source/initialization.textile19
21 files changed, 207 insertions, 153 deletions
diff --git a/actionmailer/README.rdoc b/actionmailer/README.rdoc
index 64b0333c0a..b52c993f56 100644
--- a/actionmailer/README.rdoc
+++ b/actionmailer/README.rdoc
@@ -74,9 +74,9 @@ Or you can just chain the methods together like:
== Receiving emails
-To receive emails, you need to implement a public instance method called receive that takes a
+To receive emails, you need to implement a public instance method called <tt>receive</tt> that takes a
tmail object as its single parameter. The Action Mailer framework has a corresponding class method,
-which is also called receive, that accepts a raw, unprocessed email as a string, which it then turns
+which is also called <tt>receive</tt>, that accepts a raw, unprocessed email as a string, which it then turns
into the tmail object and calls the receive instance method.
Example:
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 64d3b29513..f742f982f2 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -41,16 +41,16 @@ module ActionMailer #:nodoc:
# in the same manner as <tt>attachments[]=</tt>
#
# * <tt>headers[]=</tt> - Allows you to specify any header field in your email such
- # as <tt>headers['X-No-Spam'] = 'True'</tt>. Note, while most fields (like <tt>To:</tt>
+ # as <tt>headers['X-No-Spam'] = 'True'</tt>. Note, while most fields like <tt>To:</tt>
# <tt>From:</tt> can only appear once in an email header, other fields like <tt>X-Anything</tt>
# can appear multiple times. If you want to change a field that can appear multiple times,
- # you need to set it to nil first so that Mail knows you are replacing it, not adding
- # another field of the same name.)
+ # you need to set it to nil first so that Mail knows you are replacing it and not adding
+ # another field of the same name.
#
# * <tt>headers(hash)</tt> - Allows you to specify multiple headers in your email such
# as <tt>headers({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'})</tt>
#
- # * <tt>mail</tt> - Allows you to specify your email to send.
+ # * <tt>mail</tt> - Allows you to specify email to be sent.
#
# The hash passed to the mail method allows you to specify any header that a Mail::Message
# will accept (any valid Email header including optional fields).
@@ -66,7 +66,7 @@ module ActionMailer #:nodoc:
# format.html
# end
#
- # The block syntax is useful if also need to specify information specific to a part:
+ # The block syntax is also useful in providing information specific to a part:
#
# mail(:to => user.email) do |format|
# format.text(:content_transfer_encoding => "base64")
@@ -121,7 +121,7 @@ module ActionMailer #:nodoc:
#
# <%= users_url(:host => "example.com") %>
#
- # You will want to avoid using the <tt>name_of_route_path</tt> form of named routes because it doesn't
+ # You want to avoid using the <tt>name_of_route_path</tt> form of named routes because it doesn't
# make sense to generate relative URLs in email messages.
#
# It is also possible to set a default host that will be used in all mailers by setting the <tt>:host</tt>
@@ -132,7 +132,7 @@ module ActionMailer #:nodoc:
# Setting <tt>ActionMailer::Base.default_url_options</tt> directly is now deprecated, use the configuration
# option mentioned above to set the default host.
#
- # If you do decide to set a default <tt>:host</tt> for your mailers you will want to use the
+ # If you do decide to set a default <tt>:host</tt> for your mailers you want to use the
# <tt>:only_path => false</tt> option when using <tt>url_for</tt>. This will ensure that absolute URLs are
# generated because the <tt>url_for</tt> view helper will, by default, generate relative URLs when a
# <tt>:host</tt> option isn't explicitly provided.
@@ -154,7 +154,7 @@ module ActionMailer #:nodoc:
# detect and use multipart templates, where each template is named after the name of the action, followed
# by the content type. Each such detected template will be added as separate part to the message.
#
- # For example, if the following templates existed:
+ # For example, if the following templates exist:
# * signup_notification.text.plain.erb
# * signup_notification.text.html.erb
# * signup_notification.text.xml.builder
@@ -171,8 +171,7 @@ module ActionMailer #:nodoc:
#
# = Attachments
#
- # You can see above how to make a multipart HTML / Text email, to send attachments is just
- # as easy:
+ # Sending attachment in emails is easy:
#
# class ApplicationMailer < ActionMailer::Base
# def welcome(recipient)
@@ -189,10 +188,8 @@ module ActionMailer #:nodoc:
#
# = Inline Attachments
#
- # You can also specify that a file should be displayed inline with other HTML. For example a
- # corporate logo or a photo or the like.
- #
- # To do this is simple, in the Mailer:
+ # You can also specify that a file should be displayed inline with other HTML. This is useful
+ # if you want to display a corporate logo or a photo.
#
# class ApplicationMailer < ActionMailer::Base
# def welcome(recipient)
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb
index 4c80863e3a..5ea7636427 100644
--- a/activemodel/lib/active_model/dirty.rb
+++ b/activemodel/lib/active_model/dirty.rb
@@ -83,7 +83,10 @@ module ActiveModel
# person.name_changed? # => false
# person.name # => 'Bill'
#
- # Before modifying an attribute in-place:
+ # If an attribute is modified in-place then make use of <tt>[attribute_name]_will_change!</tt>
+ # to mark that the attribute is changing. Otherwise ActiveModel can't track changes to
+ # in-place attributes.
+ #
# person.name_will_change!
# person.name << 'y'
# person.name_change # => ['Bill', 'Billy']
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 1b9b725dd4..f540aa7f25 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -303,7 +303,7 @@ module ActiveRecord
# You can manipulate objects and associations before they are saved to the database, but there is some special behavior you should be
# aware of, mostly involving the saving of associated objects.
#
- # Unless you set the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
+ # You can set the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
# <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association. Setting it
# to +true+ will _always_ save the members, whereas setting it to +false+ will
# _never_ save the members.
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index b587abd5d0..38b91652ee 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -105,11 +105,16 @@ module ActiveRecord
# Updates a single attribute and saves the record.
# This is especially useful for boolean flags on existing records. Also note that
#
- # * validation is skipped
- # * No callbacks are invoked
- # * updated_at/updated_on column is updated if that column is available
- # * does not work on associations
- # * does not work on attr_accessor attributes. The attribute that is being updated must be column name.
+ # * The attribute being updated must be a column name.
+ # * Validation is skipped.
+ # * No callbacks are invoked.
+ # * updated_at/updated_on column is updated if that column is available.
+ # * Does not work on associations.
+ # * Does not work on attr_accessor attributes.
+ # * Does not work on new record. <tt>record.new_record?</tt> should return false for this method to work.
+ # * Updates only the attribute that is input to the method. If there are other changed attributes then
+ # those attributes are left alone. In that case even after this method has done its work <tt>record.changed?</tt>
+ # will return true.
#
def update_attribute(name, value)
raise ActiveRecordError, "#{name.to_s} is marked as readonly" if self.class.readonly_attributes.include? name.to_s
diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb
index 6c1e376745..92f7a7753d 100644
--- a/activerecord/lib/active_record/timestamp.rb
+++ b/activerecord/lib/active_record/timestamp.rb
@@ -12,6 +12,18 @@ module ActiveRecord
# Timestamps are in the local timezone by default but you can use UTC by setting:
#
# <tt>ActiveRecord::Base.default_timezone = :utc</tt>
+ #
+ # == Time Zone aware attributes
+ #
+ # By default, ActiveRecord::Base keeps all the datetime columns time zone aware by executing following code.
+ #
+ # ActiveRecord::Base.time_zone_aware_attributes = true
+ #
+ # This feature can easily be turned off by assigning value <tt>false</tt> .
+ #
+ # If your attributes are time zone aware and you desire to skip time zone conversion for certain attributes then you can do following:
+ #
+ # Topic.skip_time_zone_conversion_for_attributes = [:written_on]
module Timestamp
extend ActiveSupport::Concern
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index 0efb1a9458..8e90de110a 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -127,13 +127,6 @@ module ActiveSupport
# cache.namespace = lambda { @last_mod_time } # Set the namespace to a variable
# @last_mod_time = Time.now # Invalidate the entire cache by changing namespace
#
- # All caches support auto expiring content after a specified number of seconds.
- # To set the cache entry time to live, you can either specify +:expires_in+ as
- # an option to the constructor to have it affect all entries or to the +fetch+
- # or +write+ methods for just one entry.
- #
- # cache = ActiveSupport::Cache::MemoryStore.new(:expire_in => 5.minutes)
- # cache.write(key, value, :expire_in => 1.minute) # Set a lower value for one entry
#
# Caches can also store values in a compressed format to save space and reduce
# time spent sending data. Since there is some overhead, values must be large
@@ -173,7 +166,7 @@ module ActiveSupport
@silence = previous_silence
end
- # Set to true if cache stores should be instrumented. By default is false.
+ # Set to true if cache stores should be instrumented. Default is false.
def self.instrument=(boolean)
Thread.current[:instrument_cache_store] = boolean
end
@@ -185,7 +178,7 @@ module ActiveSupport
# Fetches data from the cache, using the given key. If there is data in
# the cache with the given key, then that data is returned.
#
- # If there is no such data in the cache (a cache miss occurred), then
+ # If there is no such data in the cache (a cache miss occurred),
# then nil will be returned. However, if a block has been passed, then
# that block will be run in the event of a cache miss. The return value
# of the block will be written to the cache under the given cache key,
@@ -209,23 +202,30 @@ module ActiveSupport
# Setting <tt>:compress</tt> will store a large cache entry set by the call
# in a compressed format.
#
- # Setting <tt>:expires_in</tt> will set an expiration time on the cache
- # entry if it is set by call.
#
- # Setting <tt>:race_condition_ttl</tt> will invoke logic on entries set with
- # an <tt>:expires_in</tt> option. If an entry is found in the cache that is
- # expired and it has been expired for less than the number of seconds specified
- # by this option and a block was passed to the method call, then the expiration
- # future time of the entry in the cache will be updated to that many seconds
- # in the and the block will be evaluated and written to the cache.
+ # Setting <tt>:expires_in</tt> will set an expiration time on the cache. All caches
+ # support auto expiring content after a specified number of seconds. This value can
+ # be specified as an option to the construction in which call all entries will be
+ # affected. Or it can be supplied to the +fetch+ or +write+ method for just one entry.
+ #
+ # cache = ActiveSupport::Cache::MemoryStore.new(:expire_in => 5.minutes)
+ # cache.write(key, value, :expire_in => 1.minute) # Set a lower value for one entry
+ #
+ # Setting <tt>:race_condition_ttl</tt> is very useful in situations where a cache entry
+ # is used very frequently unver heavy load. If a cache expires and due to heavy load
+ # seven different processes will try to read data natively and then they all will try to
+ # write to cache. To avoid that case the first process to find an expired cache entry will
+ # bump the cache expiration time by the value set in <tt>:race_condition_ttl</tt>. Yes
+ # this process is extending the time for a stale value by another few seconds. Because
+ # of extended life of the previous cache, other processes will continue to use slightly
+ # stale data for a just a big longer. In the meantime that first process will go ahead
+ # and will write into cache the new value. After that all the processes will start
+ # getting new value. The key is to keep <tt>:race_condition_ttl</tt> small.
#
- # This is very useful in situations where a cache entry is used very frequently
- # under heavy load. The first process to find an expired cache entry will then
- # become responsible for regenerating that entry while other processes continue
- # to use the slightly out of date entry. This can prevent race conditions where
- # too many processes are trying to regenerate the entry all at once. If the
- # process regenerating the entry errors out, the entry will be regenerated
- # after the specified number of seconds.
+ # If the process regenerating the entry errors out, the entry will be regenerated
+ # after the specified number of seconds. Also note that the life of stale cache is
+ # extended only if it expired recently. Otherwise a new value is generated and
+ # <tt>:race_condition_ttl</tt> does not play any role.
#
# # Set all values to expire after one minute.
# cache = ActiveSupport::Cache::MemoryCache.new(:expires_in => 1.minute)
@@ -250,6 +250,7 @@ module ActiveSupport
#
# # val_1 => "new value 1"
# # val_2 => "original value"
+ # # sleep 10 # First thread extend the life of cache by another 10 seconds
# # cache.fetch("foo") => "new value 1"
#
# Other options will be handled by the specific cache store implementation.
@@ -351,11 +352,9 @@ module ActiveSupport
results
end
- # Writes the given value to the cache, with the given key.
+ # Writes the value to the cache, with the key.
#
- # You may also specify additional options via the +options+ argument.
- # The specific cache store implementation will decide what to do with
- # +options+.
+ # Options are passed to the underlying cache implementation.
def write(name, value, options = nil)
options = merged_options(options)
instrument(:write, name, options) do |payload|
@@ -364,7 +363,7 @@ module ActiveSupport
end
end
- # Delete an entry in the cache. Returns +true+ if there was an entry to delete.
+ # Deletes an entry in the cache. Returns +true+ if an entry is deleted.
#
# Options are passed to the underlying cache implementation.
def delete(name, options = nil)
@@ -374,7 +373,7 @@ module ActiveSupport
end
end
- # Return true if the cache contains an entry with this name.
+ # Return true if the cache contains an entry for the given key.
#
# Options are passed to the underlying cache implementation.
def exist?(name, options = nil)
@@ -389,11 +388,11 @@ module ActiveSupport
end
end
- # Delete all entries whose keys match a pattern.
+ # Delete all entries with keys matching the pattern.
#
# Options are passed to the underlying cache implementation.
#
- # Not all implementations may support +delete_matched+.
+ # All implementations may not support this method.
def delete_matched(matcher, options = nil)
raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
end
@@ -402,7 +401,7 @@ module ActiveSupport
#
# Options are passed to the underlying cache implementation.
#
- # Not all implementations may support +delete_matched+.
+ # All implementations may not support this method.
def increment(name, amount = 1, options = nil)
raise NotImplementedError.new("#{self.class.name} does not support increment")
end
@@ -411,28 +410,26 @@ module ActiveSupport
#
# Options are passed to the underlying cache implementation.
#
- # Not all implementations may support +delete_matched+.
+ # All implementations may not support this method.
def decrement(name, amount = 1, options = nil)
raise NotImplementedError.new("#{self.class.name} does not support decrement")
end
- # Cleanup the cache by removing expired entries. Not all cache implementations may
- # support this method.
+ # Cleanup the cache by removing expired entries.
#
# Options are passed to the underlying cache implementation.
#
- # Not all implementations may support +delete_matched+.
+ # All implementations may not support this method.
def cleanup(options = nil)
raise NotImplementedError.new("#{self.class.name} does not support cleanup")
end
- # Clear the entire cache. Not all cache implementations may support this method.
- # You should be careful with this method since it could affect other processes
- # if you are using a shared cache.
+ # Clear the entire cache. Be careful with this method since it could
+ # affect other processes if shared cache is being used.
#
# Options are passed to the underlying cache implementation.
#
- # Not all implementations may support +delete_matched+.
+ # All implementations may not support this method.
def clear(options = nil)
raise NotImplementedError.new("#{self.class.name} does not support clear")
end
@@ -481,9 +478,9 @@ module ActiveSupport
end
end
- # Expand a key to be a consistent string value. If the object responds to +cache_key+,
- # it will be called. Otherwise, the to_param method will be called. If the key is a
- # Hash, the keys will be sorted alphabetically.
+ # Expand key to be a consistent string value. Invoke +cache_key+ if
+ # object responds to +cache_key+. Otherwise, to_param method will be
+ # called. If the key is a Hash, then keys will be sorted alphabetically.
def expanded_key(key) # :nodoc:
if key.respond_to?(:cache_key)
key = key.cache_key.to_s
@@ -500,7 +497,7 @@ module ActiveSupport
end
end
- # Prefix a key with the namespace. The two values will be delimited with a colon.
+ # Prefix a key with the namespace. Namespace and key will be delimited with a colon.
def namespaced_key(key, options)
key = expanded_key(key)
namespace = options[:namespace] if options
@@ -597,7 +594,7 @@ module ActiveSupport
end
end
- # Set a new time to live on the entry so it expires at the given time.
+ # Set a new time when the entry will expire.
def expires_at=(time)
if time
@expires_in = time.to_f - @created_at
@@ -606,12 +603,12 @@ module ActiveSupport
end
end
- # Seconds since the epoch when the cache entry will expire.
+ # Seconds since the epoch when the entry will expire.
def expires_at
@expires_in ? @created_at + @expires_in : nil
end
- # Get the size of the cached value. This could be less than value.size
+ # Returns the size of the cached value. This could be less than value.size
# if the data is compressed.
def size
if @value.nil?
diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb
index 852defeae8..f32b562368 100644
--- a/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -16,8 +16,7 @@ module ActiveSupport
# Special features:
# - Clustering and load balancing. One can specify multiple memcached servers,
# and MemCacheStore will load balance between all available servers. If a
- # server goes down, then MemCacheStore will ignore it until it goes back
- # online.
+ # server goes down, then MemCacheStore will ignore it until it comes back up.
#
# MemCacheStore implements the Strategy::LocalCache strategy which implements
# an in memory cache inside of a block.
@@ -69,7 +68,7 @@ module ActiveSupport
extend LocalCacheWithRaw
end
- # Reads multiple keys from the cache using a single call to the
+ # Reads multiple values from the cache using a single call to the
# servers for all keys. Options can be passed in the last argument.
def read_multi(*names)
options = names.extract_options!
@@ -113,7 +112,7 @@ module ActiveSupport
end
# Clear the entire cache on all memcached servers. This method should
- # be used with care when using a shared cache.
+ # be used with care when shared cache is being used.
def clear(options = nil)
@data.flush_all
end
diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb
index f5c2b8af8b..b15bb42c88 100644
--- a/activesupport/lib/active_support/cache/memory_store.rb
+++ b/activesupport/lib/active_support/cache/memory_store.rb
@@ -5,9 +5,9 @@ module ActiveSupport
# A cache store implementation which stores everything into memory in the
# same process. If you're running multiple Ruby on Rails server processes
# (which is the case if you're using mongrel_cluster or Phusion Passenger),
- # then this means that your Rails server process instances won't be able
+ # then this means that Rails server process instances won't be able
# to share cache data with each other and this may not be the most
- # appropriate cache for you.
+ # appropriate cache in that scenario.
#
# This cache has a bounded size specified by the :size options to the
# initializer (default is 32Mb). When the cache exceeds the allotted size,
@@ -47,8 +47,8 @@ module ActiveSupport
end
end
- # Prune the cache down so the entries fit within the specified memory size by removing
- # the least recently accessed entries.
+ # To ensure entries fit within the specified memory prune the cache by removing the least
+ # recently accessed entries.
def prune(target_size, max_time = nil)
return if pruning?
@pruning = true
@@ -67,7 +67,7 @@ module ActiveSupport
end
end
- # Return true if the cache is currently be pruned to remove older entries.
+ # Returns true if the cache is currently being pruned.
def pruning?
@pruning
end
diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb
index efb5ad26ab..3edba52fc4 100644
--- a/activesupport/lib/active_support/cache/strategy/local_cache.rb
+++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb
@@ -8,7 +8,7 @@ module ActiveSupport
# duration of a block. Repeated calls to the cache for the same key will hit the
# in memory cache for faster access.
module LocalCache
- # Simple memory backed cache. This cache is not thread safe but is intended only
+ # Simple memory backed cache. This cache is not thread safe and is intended only
# for serving as a temporary memory cache for a single thread.
class LocalStore < Store
def initialize
@@ -16,7 +16,7 @@ module ActiveSupport
@data = {}
end
- # Since it isn't thread safe, don't allow synchronizing.
+ # Don't allow synchronizing since it isn't thread safe,
def synchronize # :nodoc:
yield
end
@@ -39,7 +39,7 @@ module ActiveSupport
end
end
- # Use a local cache to front for the cache for the duration of a block.
+ # Use a local cache for the duration of block.
def with_local_cache
save_val = Thread.current[thread_local_key]
begin
@@ -50,8 +50,8 @@ module ActiveSupport
end
end
- # Middleware class can be inserted as a Rack handler to use a local cache for the
- # duration of a request.
+ # Middleware class can be inserted as a Rack handler to be local cache for the
+ # duration of request.
def middleware
@middleware ||= begin
klass = Class.new
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index 79e3828817..7585137aca 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -58,12 +58,12 @@ class Array
alias_method :to_default_s, :to_s
alias_method :to_s, :to_formatted_s
- # Returns a string that represents this array in XML by sending +to_xml+
- # to each element. Active Record collections delegate their representation
+ # Returns a string that represents the array in XML by invoking +to_xml+
+ # on each element. Active Record collections delegate their representation
# in XML to this method.
#
# All elements are expected to respond to +to_xml+, if any of them does
- # not an exception is raised.
+ # not then an exception is raised.
#
# The root node reflects the class name of the first element in plural
# if all elements belong to the same type and that's not Hash:
@@ -115,8 +115,8 @@ class Array
# <?xml version="1.0" encoding="UTF-8"?>
# <projects type="array"/>
#
- # By default root children have as node name the one of the root
- # singularized. You can change it with the <tt>:children</tt> option.
+ # By default name of the node for the children of root is <tt>root.singularize</tt>.
+ # You can change it with the <tt>:children</tt> option.
#
# The +options+ hash is passed downwards:
#
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
index 576366e496..bfa57fe1f7 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -2,8 +2,8 @@ require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/module/remove_method'
class Class
- # Declare a class-level attribute whose value is inheritable and
- # overwritable by subclasses:
+ # Declare a class-level attribute whose value is inheritable by subclasses.
+ # Subclasses can change their own value and it will not impact parent class.
#
# class Base
# class_attribute :setting
@@ -18,12 +18,34 @@ class Class
# Subclass.setting # => false
# Base.setting # => true
#
+ # In the above case as long as Subclass does not assign a value to setting
+ # by performing <tt>Subclass.setting = _something_ </tt>, <tt>Subclass.setting</tt>
+ # would read value assigned to parent class. Once Subclass assigns a value then
+ # the value assigned by Subclass would be returned.
+ #
# This matches normal Ruby method inheritance: think of writing an attribute
- # on a subclass as overriding the reader method.
+ # on a subclass as overriding the reader method. However, you need to be aware
+ # when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
+ # In such cases, you don't want to do changes in places but use setters:
+ #
+ # Base.setting = []
+ # Base.setting #=> []
+ # Subclass.setting #=> []
+ #
+ # # Appending in child changes both parent and child because it is the same object:
+ # Subclass.setting << :foo
+ # Base.setting #=> [:foo]
+ # Subclass.setting #=> [:foo]
+ #
+ # # Use setters to not propagate changes:
+ # Base.setting = []
+ # Subclass.setting += [:foo]
+ # Base.setting #=> []
+ # Subclass.setting #=> [:foo]
#
# For convenience, a query method is defined as well:
#
- # Subclass.setting? # => false
+ # Subclass.setting? # => false
#
# Instances may overwrite the class value in the same way:
#
diff --git a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
index feef5d2d57..4e35b1b488 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
@@ -3,11 +3,27 @@ require 'active_support/core_ext/array/extract_options'
# Extends the class object with class and instance accessors for class attributes,
# just like the native attr* accessors for instance attributes.
#
+# Note that unlike +class_attribute+, if a subclass changes the value then that would
+# also change the value for parent class. Similarly if parent class changes the value
+# then that would change the value of subclasses too.
+#
# class Person
# cattr_accessor :hair_colors
# end
#
# Person.hair_colors = [:brown, :black, :blonde, :red]
+# Person.hair_colors #=> [:brown, :black, :blonde, :red]
+# Person.new.hair_colors #=> [:brown, :black, :blonde, :red]
+#
+# To opt out of the instance writer method, pass :instance_writer => false.
+# To opt out of the instance reader method, pass :instance_reader => false.
+#
+# class Person
+# cattr_accessor :hair_colors, :instance_writer => false, :instance_reader => false
+# end
+#
+# Person.new.hair_colors = [:brown] # => NoMethodError
+# Person.new.hair_colors # => NoMethodError
class Class
def cattr_reader(*syms)
options = syms.extract_options!
diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
index 7aff05dcdf..92d6dbadd4 100644
--- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
@@ -1,14 +1,14 @@
require 'active_support/core_ext/object/duplicable'
require 'active_support/core_ext/array/extract_options'
-# Retain for backward compatibility. Methods are now included in Class.
+# Retained for backward compatibility. Methods are now included in Class.
module ClassInheritableAttributes # :nodoc:
end
-# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
+# Allows attributes to be shared within an inheritance hierarchy. Each descendant gets a copy of
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
# to, for example, an array without those additions being shared with either their parent, siblings, or
-# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
+# children. This is unlike the regular class-level attributes that are shared across the entire hierarchy.
#
# The copies of inheritable parent attributes are added to subclasses when they are created, via the
# +inherited+ hook.
diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb
index e6a213625c..c5b54318ce 100644
--- a/activesupport/lib/active_support/core_ext/date/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -40,23 +40,23 @@ class Date
end
end
- # Tells whether the Date object's date lies in the past
+ # Returns true if the Date object's date lies in the past. Otherwise returns false.
def past?
self < ::Date.current
end
- # Tells whether the Date object's date is today
+ # Returns true if the Date object's date is today.
def today?
self.to_date == ::Date.current # we need the to_date because of DateTime
end
- # Tells whether the Date object's date lies in the future
+ # Returns true if the Date object's date lies in the future.
def future?
self > ::Date.current
end
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
- # and then subtracts the specified number of seconds
+ # and then subtracts the specified number of seconds.
def ago(seconds)
to_time_in_current_zone.since(-seconds)
end
@@ -127,22 +127,22 @@ class Date
)
end
- # Returns a new Date/DateTime representing the time a number of specified months ago
+ # Returns a new Date/DateTime representing the time a number of specified months ago.
def months_ago(months)
advance(:months => -months)
end
- # Returns a new Date/DateTime representing the time a number of specified months in the future
+ # Returns a new Date/DateTime representing the time a number of specified months in the future.
def months_since(months)
advance(:months => months)
end
- # Returns a new Date/DateTime representing the time a number of specified years ago
+ # Returns a new Date/DateTime representing the time a number of specified years ago.
def years_ago(years)
advance(:years => -years)
end
- # Returns a new Date/DateTime representing the time a number of specified years in the future
+ # Returns a new Date/DateTime representing the time a number of specified years in the future.
def years_since(years)
advance(:years => years)
end
@@ -152,22 +152,22 @@ class Date
years_ago(1)
end unless method_defined?(:prev_year)
- # Short-hand for years_since(1)
+ # Shorthand for years_since(1)
def next_year
years_since(1)
end unless method_defined?(:next_year)
- # Short-hand for months_ago(1)
+ # Shorthand for months_ago(1)
def prev_month
months_ago(1)
end unless method_defined?(:prev_month)
- # Short-hand for months_since(1)
+ # Shorthand for months_since(1)
def next_month
months_since(1)
end unless method_defined?(:next_month)
- # Returns a new Date/DateTime representing the "start" of this week (i.e, Monday; DateTime objects will have time set to 0:00)
+ # Returns a new Date/DateTime representing the "start" of this week (i.e, Monday; DateTime objects will have time set to 0:00).
def beginning_of_week
days_to_monday = self.wday!=0 ? self.wday-1 : 6
result = self - days_to_monday
@@ -176,7 +176,7 @@ class Date
alias :monday :beginning_of_week
alias :at_beginning_of_week :beginning_of_week
- # Returns a new Date/DateTime representing the end of this week (Sunday, DateTime objects will have time set to 23:59:59)
+ # Returns a new Date/DateTime representing the end of this week (Sunday, DateTime objects will have time set to 23:59:59).
def end_of_week
days_to_sunday = self.wday!=0 ? 7-self.wday : 0
result = self + days_to_sunday.days
diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb
index 3664431a28..ef43fc0431 100644
--- a/activesupport/lib/active_support/lazy_load_hooks.rb
+++ b/activesupport/lib/active_support/lazy_load_hooks.rb
@@ -1,3 +1,22 @@
+# lazy_load_hooks allows rails to lazily load a lot of components and thus making the app boot faster. Because of
+# this feature now there is no need to require <tt>ActiveRecord::Base</tt> at boot time purely to apply configuration. Instead
+# a hook is registered that applies configuration once <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is used
+# as example but this feature can be applied elsewhere too.
+#
+# Here is an example where +on_load+ method is called to register a hook.
+#
+# initializer "active_record.initialize_timezone" do
+# ActiveSupport.on_load(:active_record) do
+# self.time_zone_aware_attributes = true
+# self.default_timezone = :utc
+# end
+# end
+#
+# When the entirety of +activerecord/lib/active_record/base.rb+ has been evaluated then +run_load_hooks+ is invoked.
+# The very last line of +activerecord/lib/active_record/base.rb+ is:
+#
+# ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
+#
module ActiveSupport
@load_hooks = Hash.new {|h,k| h[k] = [] }
@loaded = {}
@@ -24,4 +43,4 @@ module ActiveSupport
execute_hook(base, options, hook)
end
end
-end \ No newline at end of file
+end
diff --git a/railties/guides/source/3_0_release_notes.textile b/railties/guides/source/3_0_release_notes.textile
index 7dcaf508c6..14da650e83 100644
--- a/railties/guides/source/3_0_release_notes.textile
+++ b/railties/guides/source/3_0_release_notes.textile
@@ -1,6 +1,6 @@
h2. Ruby on Rails 3.0 Release Notes
-Rails 3.0 is ponies and rainbows! It's going to cook you dinner and fold your laundry. You're going to wonder how life was ever possible before it arrived. It's the Best Version of Rails We've Ever Done!
+Rails 3.0 is ponies and rainbows! It's going to cook you dinner and fold your laundry. You're going to wonder how life was ever possible before it arrived. It's the Best Version of Rails We've Ever Done!
But seriously now, it's really good stuff. There are all the good ideas brought over from when the Merb team joined the party and brought a focus on framework agnosticism, slimmer and faster internals, and a handful of tasty APIs. If you're coming to Rails 3.0 from Merb 1.x, you should recognize lots. If you're coming from Rails 2.x, you're going to love it too.
@@ -12,7 +12,7 @@ Even if you don't give a hoot about any of our internal cleanups, Rails 3.0 is g
* Unobtrusive JavaScript helpers with drivers for Prototype, jQuery, and more coming (end of inline JS)
* Explicit dependency management with Bundler
-On top of all that, we've tried our best to deprecate the old APIs with nice warnings. That means that you can move your existing application to Rails 3 without immediately rewriting all your old code to the latest best practices.
+On top of all that, we've tried our best to deprecate the old APIs with nice warnings. That means that you can move your existing application to Rails 3 without immediately rewriting all your old code to the latest best practices.
These release notes cover the major upgrades, but don't include every little bug fix and change. Rails 3.0 consists of almost 4,000 commits by more than 250 authors! If you want to see everything, check out the "list of commits":http://github.com/rails/rails/commits/master in the main Rails repository on GitHub.
@@ -66,7 +66,7 @@ To help with the upgrade process, a plugin named "Rails Upgrade":http://github.c
Simply install the plugin, then run +rake rails:upgrade:check+ to check your app for pieces that need to be updated (with links to information on how to update them). It also offers a task to generate a +Gemfile+ based on your current +config.gem+ calls and a task to generate a new routes file from your current one. To get the plugin, simply run the following:
<shell>
-rails plugin install git://github.com/rails/rails_upgrade.git
+ruby script/plugin install git://github.com/rails/rails_upgrade.git
</shell>
You can see an example of how that works at "Rails Upgrade is now an Official Plugin":http://omgbloglol.com/post/364624593/rails-upgrade-is-now-an-official-plugin
@@ -596,3 +596,4 @@ h3. Credits
See the "full list of contributors to Rails":http://contributors.rubyonrails.org/ for the many people who spent many hours making Rails 3. Kudos to all of them.
Rails 3.0 Release Notes were compiled by "Mikel Lindsaar":http://lindsaar.net.
+
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index fc59df9fe4..fcf4ae29ba 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -1135,21 +1135,6 @@ Since values are copied when a subclass is defined, if the base class changes th
NOTE: Defined in +active_support/core_ext/class/inheritable_attributes.rb+.
-There's a related macro called +superclass_delegating_accessor+, however, that does not copy the value when the base class is subclassed. Instead, it delegates reading to the superclass as long as the attribute is not set via its own writer. For example, +ActionMailer::Base+ defines +delivery_method+ this way:
-
-<ruby>
-module ActionMailer
- class Base
- superclass_delegating_accessor :delivery_method
- self.delivery_method = :smtp
- end
-end
-</ruby>
-
-If for whatever reason an application loads the definition of a mailer class and after that sets +ActionMailer::Base.delivery_method+, the mailer class will still see the new value. In addition, the mailer class is able to change the +delivery_method+ without affecting the value in the parent using its own inherited class attribute writer.
-
-NOTE: Defined in +active_support/core_ext/class/delegating_attributes.rb+.
-
h4. Subclasses & Descendants
h5. +subclasses+
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index 2ab28596d8..9e0c7cd060 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -181,7 +181,7 @@ There are only a few configuration options for Action View, starting with four o
* +config.action_view.warn_cache_misses+ tells Rails to display a warning whenever an action results in a cache miss on your view paths. The default is +false+.
-* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| "&lt;div class=\"field_with_errors\"&gt;#{html_tag}&lt;/div&gt;" }</tt>
+* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| %Q(%&lt;div class=&quot;field_with_errors&quot;&gt;#{html_tag}&lt;/div&gt;).html_safe }</tt>
* +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+.
diff --git a/railties/guides/source/contributing_to_rails.textile b/railties/guides/source/contributing_to_rails.textile
index f0e9a4b5ec..094a4ef1a9 100644
--- a/railties/guides/source/contributing_to_rails.textile
+++ b/railties/guides/source/contributing_to_rails.textile
@@ -48,7 +48,7 @@ h4. Install git
Rails uses git for source code control. You won’t be able to do anything without the Rails source code, and this is a prerequisite. The "git homepage":http://git-scm.com/ has installation instructions. If you’re on OS X, use the "Git for OS X":http://code.google.com/p/git-osx-installer/ installer. If you're unfamiliar with git, there are a variety of resources on the net that will help you learn more:
-* "Everyday Git":http://www.kernel.org/pub/software/scm/git/docs/everyday.html will teach you just enough about git to get by.
+* "Everyday Git":http://www.kernel.org/pub/software/scm/git/docs/everyday.html will teach you just enough about git to get by.
* The "PeepCode screencast":https://peepcode.com/products/git on git ($9) is easier to follow.
* "GitHub":http://github.com/guides/home offers links to a variety of git resources.
* "Pro Git":http://progit.org/book/ is an entire book about git with a Creative Commons license.
@@ -58,7 +58,7 @@ h4. Get the Rails Source Code
Don’t fork the main Rails repository. Instead, you want to clone it to your own computer. Navigate to the folder where you want the source code (it will create its own /rails subdirectory) and run:
<shell>
-git clone git://github.com/rails/rails.git
+git clone git://github.com/rails/rails.git
cd rails
</shell>
@@ -66,8 +66,10 @@ h4. Set up and Run the Tests
All of the Rails tests must pass with any code you submit, otherwise you have no chance of getting code accepted. This means you need to be able to run the tests. First, you need to install all Rails dependencies with bundler:
+NOTE: Ensure you install bundler v1.0
+
<shell>
-gem install bundler
+gem install -v=1.0.0.rc.1 bundler
bundle install --without db
</shell>
@@ -90,7 +92,7 @@ By default, when you run Active Record tests, it will execute the test suite thr
<shell>
cd activerecord
-rake test_sqlite3
+rake test_sqlite3
rake test_sqlite3 TEST=test/cases/validations_test.rb
</shell>
@@ -258,15 +260,15 @@ h4. Update Rails
Update your copy of Rails. It’s pretty likely that other changes to core Rails have happened while you were working. Go get them:
<shell>
-git checkout master
-git pull
+git checkout master
+git pull
</shell>
Now reapply your patch on top of the latest changes:
<shell>
-git checkout my_new_branch
-git rebase master
+git checkout my_new_branch
+git rebase master
</shell>
No conflicts? Tests still pass? Change still seems reasonable to you? Then move on.
@@ -276,8 +278,8 @@ h4. Create a Patch
Now you can create a patch file to share with other developers (and with the Rails core team). Still in your branch, run
<shell>
-git commit -a
-git format-patch master --stdout > my_new_patch.diff
+git commit -a
+git format-patch master --stdout > my_new_patch.diff
</shell>
Sanity check the results of this operation: open the diff file in your text editor of choice and make sure that no unintended changes crept in.
@@ -302,4 +304,5 @@ h3. Changelog
* April 6, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* August 1, 2009: Updates/amplifications by "Mike Gunderloy":credits.html#mgunderloy
-* March 2, 2009: Initial draft by "Mike Gunderloy":credits.html#mgunderloy \ No newline at end of file
+* March 2, 2009: Initial draft by "Mike Gunderloy":credits.html#mgunderloy
+
diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile
index 305602e57d..28afdb3bd0 100644
--- a/railties/guides/source/initialization.textile
+++ b/railties/guides/source/initialization.textile
@@ -258,28 +258,23 @@ This file goes on to define some classes that will be automatically loaded using
h4. Lazy Hooks
-At the top if the +ActiveSupport::Autoload+ module is the +def self.extended+ method:
-
-<ruby>
- def self.extended(base)
- base.extend(LazyLoadHooks)
- end
-</ruby>
-
-This is called when we extend this module into one of our classes or modules, such is the case later on when we call +extend ActiveSupport::LazyLoadHooks+ not only in the +ActiveSupport+ module, but in all of the Railtie modules (+ActiveRecord+ and so on), as well as in a couple of places.
-
+ActiveSupport::LazyLoadHooks+ is responsible for defining methods used for running hooks that are defined during the initialization process, such as the one defined inside the +active_record.initialize_timezone+ initializer:
<ruby>
initializer "active_record.initialize_timezone" do
- ActiveRecord.base_hook do
+ ActiveSupport.on_load(:active_record) do
self.time_zone_aware_attributes = true
self.default_timezone = :utc
end
end
</ruby>
-When the initializer is ran it defines a +base_hook+ for +ActiveRecord+ and will only run it when +run_base_hooks+ is called, which in the case of Active Record, is ran after the entirety of +activerecord/lib/active_record/base.rb+ has been evaluated.
+When the initializer runs it invokes method +on_load+ for +ActiveRecord+ and the block passed to it would be called only when +run_load_hooks+ is called.
+When the entirety of +activerecord/lib/active_record/base.rb+ has been evaluated then +run_load_hooks+ is invoked. The very last line of +activerecord/lib/active_record/base.rb+ is:
+
+<ruby>
+ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
+</ruby>
h4. +require 'active_support'+ cont'd.