Improve documentation.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9093 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Pratik Naik 2008-03-26 12:27:52 +00:00
parent 5c47ceb30b
commit ca9413674e
45 changed files with 468 additions and 173 deletions

View File

@ -1,5 +1,7 @@
*SVN*
* Improve documentation. [Radar, Jan De Poorter, chuyeow, xaviershay, danger, miloops, Xavier Noria, Sunny Ripert]
* Fixed that FormHelper#radio_button would produce invalid ids #11298 [harlancrystal]
* Added :confirm option to submit_tag #11415 [miloops]

View File

@ -227,6 +227,13 @@ module ActionController
#
# <% form_for :message, @message, :url => message_path(@message), :html => {:method => :put} do |f| %>
#
# or
#
# <% form_for @message do |f| %>
#
# which takes into account whether <tt>@message</tt> is a new record or not and generates the
# path and method accordingly.
#
# The #resources method accepts the following options to customize the resulting routes:
# * <tt>:collection</tt> - add named routes for other actions that operate on the collection.
# Takes a hash of <tt>#{action} => #{method}</tt>, where method is <tt>:get</tt>/<tt>:post</tt>/<tt>:put</tt>/<tt>:delete</tt>

View File

@ -49,7 +49,7 @@ module ActionView
# * <tt>:url</tt>: The URL for this feed. Defaults to the current URL.
# * <tt>:schema_date</tt>: The date at which the tag scheme for the feed was first used. A good default is the year you
# created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified,
# 2005 is used (as a "I don't care"-value).
# 2005 is used (as an "I don't care" value).
#
# Other namespaces can be added to the root element:
#

View File

@ -76,6 +76,7 @@ module ActionView
# values for the fields.
#
# <% form_for :person, @person, :url => { :action => "update" } do |f| %>
# <%= f.error_messages %>
# First name: <%= f.text_field :first_name %>
# Last name : <%= f.text_field :last_name %>
# Biography : <%= f.text_area :biography %>
@ -85,7 +86,8 @@ module ActionView
# Worth noting is that the form_for tag is called in a ERb evaluation block, not an ERb output block. So that's <tt><% %></tt>,
# not <tt><%= %></tt>. Also worth noting is that form_for yields a <tt>form_builder</tt> object, in this example as <tt>f</tt>, which emulates
# the API for the stand-alone FormHelper methods, but without the object name. So instead of <tt>text_field :person, :name</tt>,
# you get away with <tt>f.text_field :name</tt>.
# you get away with <tt>f.text_field :name</tt>. Notice that you can even do <tt><%= f.error_messages %></tt> to display the
# error messsages of the model object in question.
#
# Even further, the form_for method allows you to more easily escape the instance variable convention. So while the stand-alone
# approach would require <tt>text_field :person, :name, :object => person</tt>
@ -405,7 +407,7 @@ module ActionView
# ==== Examples
# # Let's say that @post.validated? is 1:
# check_box("post", "validated")
# # => <input type="checkbox" id="post_validate" name="post[validated]" value="1" checked="checked" />
# # => <input type="checkbox" id="post_validated" name="post[validated]" value="1" />
# # <input name="post[validated]" type="hidden" value="0" />
#
# # Let's say that @puppy.gooddog is "no":
@ -413,8 +415,8 @@ module ActionView
# # => <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
# # <input name="puppy[gooddog]" type="hidden" value="no" />
#
# check_box("eula", "accepted", {}, "yes", "no", :class => 'eula_check')
# # => <input type="checkbox" id="eula_accepted" name="eula[accepted]" value="no" />
# check_box("eula", "accepted", { :class => 'eula_check' }, "yes", "no")
# # => <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
# # <input name="eula[accepted]" type="hidden" value="no" />
#
def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
@ -430,13 +432,13 @@ module ActionView
# # Let's say that @post.category returns "rails":
# radio_button("post", "category", "rails")
# radio_button("post", "category", "java")
# # => <input type="radio" id="post_category" name="post[category]" value="rails" checked="checked" />
# # <input type="radio" id="post_category" name="post[category]" value="java" />
# # => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
# # <input type="radio" id="post_category_java" name="post[category]" value="java" />
#
# radio_button("user", "receive_newsletter", "yes")
# radio_button("user", "receive_newsletter", "no")
# # => <input type="radio" id="user_receive_newsletter" name="user[receive_newsletter]" value="yes" />
# # <input type="radio" id="user_receive_newsletter" name="user[receive_newsletter]" value="no" checked="checked" />
# # => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
# # <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
def radio_button(object_name, method, tag_value, options = {})
InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_radio_button_tag(tag_value, options)
end

View File

@ -1,5 +1,7 @@
*SVN*
* Improve documentation. [Radar, Jan De Poorter, chuyeow, xaviershay, danger, miloops, Xavier Noria, Sunny Ripert]
* Fixed that ActiveRecord#Base.find_or_create/initialize would not honor attr_protected/accessible when used with a hash #11422 [miloops]
* Added ActiveRecord#Base.all/first/last as aliases for find(:all/:first/:last) #11413 [nkallen, thechrisoshow]

View File

@ -176,11 +176,11 @@ end
# Some times you don't care about the content of the fixtures as much as you care about the volume. In these cases, you can
# mix ERb in with your YAML or CSV fixtures to create a bunch of fixtures for load testing, like:
#
# <% for i in 1..1000 %>
# fix_<%= i %>:
# id: <%= i %>
# name: guy_<%= 1 %>
# <% end %>
# <% for i in 1..1000 %>
# fix_<%= i %>:
# id: <%= i %>
# name: guy_<%= 1 %>
# <% end %>
#
# This will create 1000 very simple YAML fixtures.
#

View File

@ -91,13 +91,30 @@ module ActiveRecord
#
# The Rails package has several tools to help create and apply migrations.
#
# To generate a new migration, use <tt>script/generate migration MyNewMigration</tt>
# To generate a new migration, you can use
# script/generate migration MyNewMigration
#
# where MyNewMigration is the name of your migration. The generator will
# create a file <tt>nnn_my_new_migration.rb</tt> in the <tt>db/migrate/</tt>
# create an empty migration file <tt>nnn_my_new_migration.rb</tt> in the <tt>db/migrate/</tt>
# directory where <tt>nnn</tt> is the next largest migration number.
#
# You may then edit the <tt>self.up</tt> and <tt>self.down</tt> methods of
# MyNewMigration.
#
# There is a special syntactic shortcut to generate migrations that add fields to a table.
# script/generate migration add_fieldname_to_tablename fieldname:string
#
# This will generate the file <tt>nnn_add_fieldname_to_tablename</tt>, which will look like this:
# class AddFieldnameToTablename < ActiveRecord::Migration
# def self.up
# add_column :tablenames, :fieldname, :string
# end
#
# def self.down
# remove_column :tablenames, :fieldname
# end
# end
#
# To run migrations against the currently configured database, use
# <tt>rake db:migrate</tt>. This will update the database by running all of the
# pending migrations, creating the <tt>schema_info</tt> table if missing.

View File

@ -8,37 +8,32 @@ module ActiveRecord #:nodoc:
#
# konata = User.find(1)
# konata.to_json
#
# {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true}
# # => {"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:
#
# konata.to_json(:only => [ :id, :name ])
#
# {"id": 1, "name": "Konata Izumi"}
# # => {"id": 1, "name": "Konata Izumi"}
#
# konata.to_json(:except => [ :id, :created_at, :age ])
#
# {"name": "Konata Izumi", "awesome": true}
# # => {"name": "Konata Izumi", "awesome": true}
#
# To include any methods on the model, use :methods.
#
# konata.to_json(:methods => :permalink)
#
# {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "permalink": "1-konata-izumi"}
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "permalink": "1-konata-izumi"}
#
# To include associations, use :include.
#
# konata.to_json(:include => :posts)
#
# {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
# {"id": 2, author_id: 1, "title": "So I was thinking"}]}
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
# {"id": 2, author_id: 1, "title": "So I was thinking"}]}
#
# 2nd level and higher order associations work as well:
#
@ -46,13 +41,12 @@ module ActiveRecord #:nodoc:
# :include => { :comments => {
# :only => :body } },
# :only => :title } })
#
# {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "posts": [{"comments": [{"body": "1st post!"}, {"body": "Second!"}],
# "title": "Welcome to the weblog"},
# {"comments": [{"body": "Don't think too hard"}],
# "title": "So I was thinking"}]}
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "posts": [{"comments": [{"body": "1st post!"}, {"body": "Second!"}],
# "title": "Welcome to the weblog"},
# {"comments": [{"body": "Don't think too hard"}],
# "title": "So I was thinking"}]}
def to_json(options = {})
JsonSerializer.new(self, options).to_s
end

View File

@ -1,11 +1,11 @@
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.
# 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.
#
# By default the generated XML document will include the processing
# instruction and all object's attributes. For example:
# instruction and all the object's attributes. For example:
#
# <?xml version="1.0" encoding="UTF-8"?>
# <topic>
@ -23,10 +23,10 @@ module ActiveRecord #:nodoc:
# </topic>
#
# This behavior can be controlled with :only, :except,
# :skip_instruct, :skip_types and :dasherize. The :only and
# :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
# set :dasherize to false. To not have the column type included
# in the XML output, set :skip_types to true.
#
# For instance:
@ -68,6 +68,36 @@ module ActiveRecord #:nodoc:
# </account>
# </firm>
#
# To include deeper levels of associations pass a hash like this:
#
# firm.to_xml :include => {:account => {}, :clients => {:include => :address}}
# <?xml version="1.0" encoding="UTF-8"?>
# <firm>
# <id type="integer">1</id>
# <rating type="integer">1</rating>
# <name>37signals</name>
# <clients type="array">
# <client>
# <rating type="integer">1</rating>
# <name>Summit</name>
# <address>
# ...
# </address>
# </client>
# <client>
# <rating type="integer">1</rating>
# <name>Microsoft</name>
# <address>
# ...
# </address>
# </client>
# </clients>
# <account>
# <id type="integer">1</id>
# <credit-limit type="integer">50</credit-limit>
# </account>
# </firm>
#
# To include any methods on the object(s) being called use :methods
#
# firm.to_xml :methods => [ :calculated_earnings, :real_earnings ]
@ -78,7 +108,7 @@ module ActiveRecord #:nodoc:
# <real-earnings>5</real-earnings>
# </firm>
#
# To call any Proc's on the object(s) use :procs. The Proc's
# 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.
#
@ -90,7 +120,7 @@ module ActiveRecord #:nodoc:
# <abc>def</abc>
# </firm>
#
# Alternatively, you can also just 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
@ -108,7 +138,7 @@ module ActiveRecord #:nodoc:
# </firm>
#
# You can override the to_xml method in your ActiveRecord::Base
# subclasses if you need to. The general form of doing this is
# subclasses if you need to. The general form of doing this is:
#
# class IHaveMyOwnXML < ActiveRecord::Base
# def to_xml(options = {})
@ -155,13 +185,6 @@ module ActiveRecord #:nodoc:
!options.has_key?(:dasherize) || options[:dasherize]
end
# To replicate the behavior in ActiveRecord#attributes,
# :except takes precedence over :only. If :only 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.
def serializable_attributes
serializable_attribute_names.collect { |name| Attribute.new(name, @record) }
end
@ -251,7 +274,7 @@ module ActiveRecord #:nodoc:
# There is a significant speed improvement if the value
# does not need to be escaped, as #tag! escapes all values
# to ensure that valid XML is generated. For known binary
# to ensure that valid XML is generated. For known binary
# values, it is at least an order of magnitude faster to
# Base64 encode binary values and directly put them in the
# output XML than to pass the original value or the Base64

View File

@ -5,7 +5,7 @@ module ActiveRecord
# Timestamping can be turned off by setting
# <tt>ActiveRecord::Base.record_timestamps = false</tt>
#
# Timestamps are in the local timezone by default but can use UTC by setting
# Timestamps are in the local timezone by default but you can use UTC by setting
# <tt>ActiveRecord::Base.default_timezone = :utc</tt>
module Timestamp
def self.included(base) #:nodoc:

View File

@ -1,5 +1,7 @@
*SVN*
* Improve documentation. [Radar, Jan De Poorter, chuyeow, xaviershay, danger, miloops, Xavier Noria, Sunny Ripert]
* Use HEAD instead of GET in exists? [bscofield]
* Fix small documentation typo. Closes #10670 [l.guidi]

View File

@ -1,5 +1,7 @@
*SVN*
* Improve documentation. [Radar, Jan De Poorter, chuyeow, xaviershay, danger, miloops, Xavier Noria, Sunny Ripert]
* Ensure that TimeWithZone#to_yaml works when passed a YAML::Emitter. [rick]
* Ensure correct TimeWithZone#to_date [Geoff Buesing]

View File

@ -1,6 +1,11 @@
# Ruby 1.9 introduces BasicObject which differs slighly from Builder's BlankSlate
# that had been used so far ActiveSupport::BasicObject provides a barebones object with
# the same method on both versions.
# A base class with no predefined methods that tries to behave like Builder's
# BlankSlate in Ruby 1.9. In Ruby pre-1.9, this is actually the
# Builder::BlankSlate class.
#
# Ruby 1.9 introduces BasicObject which differs slightly from Builder's
# BlankSlate that has been used so far. ActiveSupport::BasicObject provides a
# barebones base class that emulates Builder::BlankSlate while still relying on
# Ruby 1.9's BasicObject in Ruby 1.9.
module ActiveSupport
if RUBY_VERSION >= '1.9'
class BasicObject < ::BasicObject

View File

@ -24,7 +24,8 @@ module ActiveSupport #:nodoc:
end
end
# Calls to_param on all its elements and joins the result with slashes. This is used by url_for in Action Pack.
# Calls <tt>to_param</tt> on all its elements and joins the result with
# slashes. This is used by <tt>url_for</tt> in Action Pack.
def to_param
map(&:to_param).join '/'
end
@ -32,8 +33,9 @@ module ActiveSupport #:nodoc:
# Converts an array into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
# param name.
#
# ==== Example:
# ['Rails', 'coding'].to_query('hobbies') => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
# Example:
#
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
def to_query(key)
collect { |value| value.to_query("#{key}[]") } * '&'
end
@ -45,6 +47,15 @@ module ActiveSupport #:nodoc:
end
end
# Converts a collection of elements into a formatted string by calling
# <tt>to_s</tt> on all elements and joining them:
#
# Blog.find(:all).to_formatted_s # => "First PostSecond PostThird Post"
#
# Adding in the <tt>:db</tt> argument as the format yields a prettier
# output:
#
# Blog.find(:all).to_formatted_s(:db) # => "First Post,Second Post,Third Post"
def to_formatted_s(format = :default)
case format
when :db
@ -58,6 +69,48 @@ module ActiveSupport #:nodoc:
end
end
# Returns a string that represents this array in XML by sending
# <tt>to_xml</tt> to each element.
#
# All elements are expected to respond to <tt>to_xml</tt>, if any of
# them does not 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 <tt>Hash</tt>.
# Otherwise the root element is "records".
#
# Root children have as node name the one of the root singularized.
#
# Example:
#
# [{:foo => 1, :bar => 2}, {:baz => 3}].to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <records type="array">
# <record>
# <bar type="integer">2</bar>
# <foo type="integer">1</foo>
# </record>
# <record>
# <baz type="integer">3</baz>
# </record>
# </records>
#
# The +options+ hash is passed downwards:
#
# [Message.find(:first)].to_xml(:skip_types => true)
#
# <?xml version="1.0" encoding="UTF-8"?>
# <messages>
# <message>
# <created-at>2008-03-07T09:58:18+01:00</created-at>
# <id>1</id>
# <name>1</name>
# <updated-at>2008-03-07T09:58:18+01:00</updated-at>
# <user-id>1</user-id>
# </message>
# </messages>
#
def to_xml(options = {})
raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }

View File

@ -8,7 +8,7 @@ module ActiveSupport #:nodoc:
# slots with specified value (<tt>nil</tt> by default) unless it is
# <tt>false</tt>.
#
# E.g.
# Examples:
#
# %w(1 2 3 4 5 6 7).in_groups_of(3) {|g| p g}
# ["1", "2", "3"]
@ -45,7 +45,7 @@ module ActiveSupport #:nodoc:
# Divide the array into one or more subarrays based on a delimiting +value+
# or the result of an optional block.
#
# ex.
# Examples:
#
# [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]

View File

@ -1,5 +1,5 @@
class Object
# An object is blank if it's nil, empty, or a whitespace string.
# An object is blank if it's false, empty, or a whitespace string.
# For example, "", " ", nil, [], and {} are blank.
#
# This simplifies

View File

@ -1,12 +1,21 @@
class Class #:nodoc:
# Will unassociate the class with its subclasses as well as uninitializing the subclasses themselves.
# >> Integer.remove_subclasses
# => [Bignum, Fixnum]
# >> Fixnum
# NameError: uninitialized constant Fixnum
def remove_subclasses
Object.remove_subclasses_of(self)
end
# Returns a list of classes that inherit from this class in an array.
# Example: Integer.subclasses => ["Bignum", "Fixnum"]
def subclasses
Object.subclasses_of(self).map { |o| o.to_s }
end
# Allows you to remove individual subclasses or a selection of subclasses from a class without removing all of them.
def remove_class(*klasses)
klasses.flatten.each do |klass|
# Skip this class if there is nothing bound to this name

View File

@ -16,10 +16,12 @@ module ActiveSupport #:nodoc:
end
module ClassMethods
# Finds yesterday's date, in the format similar to: Mon, 17 Mar 2008
def yesterday
::Date.today.yesterday
end
# Finds tommorrow's date, in the format similar to: Tue, 18 Mar 2008
def tomorrow
::Date.today.tomorrow
end

View File

@ -2,7 +2,7 @@ module Enumerable
# Collect an enumerable into sets, grouped by the result of a block. Useful,
# for example, for grouping records by date.
#
# e.g.
# Example:
#
# latest_transcripts.group_by(&:day).each do |day, transcripts|
# p "#{day} -> #{transcripts.map(&:class) * ', '}"
@ -23,18 +23,21 @@ module Enumerable
# Calculates a sum from the elements. Examples:
#
# payments.sum { |p| p.price * p.tax_rate }
# payments.sum(&:price)
# payments.sum { |p| p.price * p.tax_rate }
# payments.sum(&:price)
#
# This is instead of payments.inject { |sum, p| sum + p.price }
# This is instead of
#
# payments.inject { |sum, p| sum + p.price }
#
# Also calculates sums without the use of a block:
#
# [5, 15, 10].sum # => 30
#
# The default identity (sum of an empty list) is zero.
# However, you can override this default:
#
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
#
def sum(identity = 0, &block)
return identity unless size > 0

View File

@ -3,16 +3,16 @@ require 'tempfile'
# Write to a file atomically. Useful for situations where you don't
# want other processes or threads to see half-written files.
#
# File.atomic_write("important.file") do |file|
# file.write("hello")
# end
# File.atomic_write("important.file") do |file|
# file.write("hello")
# end
#
# If your temp directory is not on the same filesystem as the file you're
# trying to write, you can provide a different temporary directory.
#
# File.atomic_write("/data/something.imporant", "/data/tmp") do |f|
# file.write("hello")
# end
# File.atomic_write("/data/something.important", "/data/tmp") do |f|
# file.write("hello")
# end
def File.atomic_write(file_name, temp_dir = Dir.tmpdir)
temp_file = Tempfile.new(File.basename(file_name), temp_dir)
yield temp_file

View File

@ -1,5 +1,6 @@
# This class has dubious semantics and we only have it so that
# people can write params[:key] instead of params['key']
# and they get the same value for both keys.
class HashWithIndifferentAccess < Hash
def initialize(constructor = {})
@ -22,10 +23,38 @@ class HashWithIndifferentAccess < Hash
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
alias_method :regular_update, :update unless method_defined?(:regular_update)
#
# Assigns a new value to the hash.
#
# Example:
#
# hash = HashWithIndifferentAccess.new
# hash[:key] = "value"
#
def []=(key, value)
regular_writer(convert_key(key), convert_value(value))
end
#
# Updates the instantized hash with values from the second.
#
# Example:
#
# >> hash_1 = HashWithIndifferentAccess.new
# => {}
#
# >> hash_1[:key] = "value"
# => "value"
#
# >> hash_2 = HashWithIndifferentAccess.new
# => {}
#
# >> hash_2[:key] = "New Value!"
# => "New Value!"
#
# >> hash_1.update(hash_2)
# => {"key"=>"New Value!"}
#
def update(other_hash)
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
self
@ -33,6 +62,7 @@ class HashWithIndifferentAccess < Hash
alias_method :merge!, :update
# Checks the hash for a key matching the argument passed in
def key?(key)
super(convert_key(key))
end
@ -41,22 +71,28 @@ class HashWithIndifferentAccess < Hash
alias_method :has_key?, :key?
alias_method :member?, :key?
# Fetches the value for the specified key, same as doing hash[key]
def fetch(key, *extras)
super(convert_key(key), *extras)
end
# Returns an array of the values at the specified indicies.
def values_at(*indices)
indices.collect {|key| self[convert_key(key)]}
end
# Returns an exact copy of the hash.
def dup
HashWithIndifferentAccess.new(self)
end
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
# Does not overwrite the existing hash.
def merge(hash)
self.dup.update(hash)
end
# Removes a specified key from the hash.
def delete(key)
super(convert_key(key))
end

View File

@ -10,10 +10,13 @@ module ActiveSupport #:nodoc:
#
# The default :size and :velocity is only set if the +options+ passed in doesn't already have those keys set.
module ReverseMerge
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
def reverse_merge(other_hash)
other_hash.merge(self)
end
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
# Modifies the receiver in place.
def reverse_merge!(other_hash)
replace(reverse_merge(other_hash))
end

View File

@ -1,11 +1,14 @@
module ActiveSupport #:nodoc:
module CoreExtensions #:nodoc:
module Integer #:nodoc:
# For checking if a fixnum is even or odd.
# * 1.even? # => false
# * 1.odd? # => true
# * 2.even? # => true
# * 2.odd? # => false
# For checking if a fixnum is even or odd.
#
# Examples:
#
# 1.even? # => false
# 1.odd? # => true
# 2.even? # => true
# 2.odd? # => false
module EvenOdd
def multiple_of?(number)
self % number == 0

View File

@ -7,7 +7,8 @@ module ActiveSupport #:nodoc:
# Ordinalize turns a number into an ordinal string used to denote the
# position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
#
# Examples
# Examples:
#
# 1.ordinalize # => "1st"
# 2.ordinalize # => "2nd"
# 1002.ordinalize # => "1002nd"

View File

@ -42,6 +42,14 @@ module Kernel
stream.reopen(old_stream)
end
# Blocks and ignores any exception passed as argument if raised within the block.
#
# suppress(ZeroDivisionError) do
# 1/0
# puts "This code is NOT reached"
# end
#
# puts "This code gets executed and nothing related to ZeroDivisionError was seen"
def suppress(*exception_classes)
begin yield
rescue Exception => e

View File

@ -13,7 +13,8 @@ class Module
end
end
# Declare attributes backed by 'internal' instance variables names.
# Declare an attribute reader and writer backed by an internally-named instance
# variable.
def attr_internal_accessor(*attrs)
attr_internal_reader(*attrs)
attr_internal_writer(*attrs)

View File

@ -1,4 +1,23 @@
class Module
# Returns the classes in the current ObjectSpace where this module has been
# mixed in according to Module#included_modules.
#
# module M
# end
#
# module N
# include M
# end
#
# class C
# include M
# end
#
# class D < C
# end
#
# p M.included_in_classes # => [C, D]
#
def included_in_classes
classes = []
ObjectSpace.each_object(Class) { |k| classes << k if k.included_modules.include?(self) }

View File

@ -1,13 +1,38 @@
class Module
# Return the module which contains this one; if this is a root module, such as
# +::MyModule+, then Object is returned.
# Returns the module which contains this one according to its name.
#
# module M
# module N
# end
# end
# X = M::N
#
# p M::N.parent # => M
# p X.parent # => M
#
# The parent of top-level and anonymous modules is Object.
#
# p M.parent # => Object
# p Module.new.parent # => Object
#
def parent
parent_name = name.split('::')[0..-2] * '::'
parent_name.empty? ? Object : parent_name.constantize
end
# Return all the parents of this module, ordered from nested outwards. The
# receiver is not contained within the result.
# Returns all the parents of this module according to its name, ordered from
# nested outwards. The receiver is not contained within the result.
#
# module M
# module N
# end
# end
# X = M::N
#
# p M.parents # => [Object]
# p M::N.parents # => [M, Object]
# p X.parents # => [M, Object]
#
def parents
parents = []
parts = name.split('::')[0..-2]
@ -20,7 +45,7 @@ class Module
end
if RUBY_VERSION < '1.9'
# Return the constants that have been defined locally by this object and
# Returns the constants that have been defined locally by this object and
# not in an ancestor. This method is exact if running under Ruby 1.9. In
# previous versions it may miss some constants if their definition in some
# ancestor is identical to their definition in the receiver.

View File

@ -1,4 +1,14 @@
class Module
# Returns String#underscore applied to the module name minus trailing classes.
#
# ActiveRecord.as_load_path # => "active_record"
# ActiveRecord::Associations.as_load_path # => "active_record/associations"
# ActiveRecord::Base.as_load_path # => "active_record" (Base is a class)
#
# The Kernel module gives an empty string by definition.
#
# Kernel.as_load_path # => ""
# Math.as_load_path # => "math"
def as_load_path
if self == Object || self == Kernel
''

View File

@ -6,6 +6,16 @@ class Object
end
end
# Returns a hash that maps instance variable names without "@" to their
# corresponding values. Keys are strings both in Ruby 1.8 and 1.9.
#
# class C
# def initialize(x, y)
# @x, @y = x, y
# end
# end
#
# C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
def instance_values #:nodoc:
instance_variables.inject({}) do |values, name|
values[name.to_s[1..-1]] = instance_variable_get(name)
@ -13,10 +23,44 @@ class Object
end
end
# Returns an array of instance variable names including "@". They are strings
# both in Ruby 1.8 and 1.9.
#
# class C
# def initialize(x, y)
# @x, @y = x, y
# end
# end
#
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
def instance_variable_names
instance_variables.map(&:to_s)
end
# Copies the instance variables of +object+ into self.
#
# Instance variable names in the +exclude+ array are ignored. If +object+
# responds to <tt>protected_instance_variables</tt> the ones returned are
# also ignored. For example, Rails controllers implement that method.
#
# In both cases strings and symbols are understood, and they have to include
# the at sign.
#
# class C
# def initialize(x, y, z)
# @x, @y, @z = x, y, z
# end
#
# def protected_instance_variables
# %w(@z)
# end
# end
#
# a = C.new(0, 1, 2)
# b = C.new(3, 4, 5)
#
# a.copy_instance_variables_from(b, [:@y])
# # a is now: @x = 3, @y = 1, @z = 2
def copy_instance_variables_from(object, exclude = []) #:nodoc:
exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables

View File

@ -13,7 +13,12 @@ module ActiveSupport #:nodoc:
alias_method :to_s, :to_formatted_s
end
end
# Gives a human readable format of the range.
#
# Example:
#
# >> [1..100].to_formatted_s
# => "1..100"
def to_formatted_s(format = :default)
RANGE_FORMATS[format] ? RANGE_FORMATS[format].call(first, last) : to_default_s
end

View File

@ -5,44 +5,42 @@ module ActiveSupport #:nodoc:
module String #:nodoc:
# String inflections define new methods on the String class to transform names for different purposes.
# For instance, you can figure out the name of a database from the name of a class.
# "ScaleScore".tableize => "scale_scores"
#
# "ScaleScore".tableize # => "scale_scores"
module Inflections
# Returns the plural form of the word in the string.
#
# Examples
# "post".pluralize #=> "posts"
# "octopus".pluralize #=> "octopi"
# "sheep".pluralize #=> "sheep"
# "words".pluralize #=> "words"
# "the blue mailman".pluralize #=> "the blue mailmen"
# "CamelOctopus".pluralize #=> "CamelOctopi"
# "post".pluralize # => "posts"
# "octopus".pluralize # => "octopi"
# "sheep".pluralize # => "sheep"
# "words".pluralize # => "words"
# "the blue mailman".pluralize # => "the blue mailmen"
# "CamelOctopus".pluralize # => "CamelOctopi"
def pluralize
Inflector.pluralize(self)
end
# The reverse of pluralize, returns the singular form of a word in a string.
# The reverse of +pluralize+, returns the singular form of a word in a string.
#
# Examples
# "posts".singularize #=> "post"
# "octopi".singularize #=> "octopus"
# "sheep".singluarize #=> "sheep"
# "word".singluarize #=> "word"
# "the blue mailmen".singularize #=> "the blue mailman"
# "CamelOctopi".singularize #=> "CamelOctopus"
# "posts".singularize # => "post"
# "octopi".singularize # => "octopus"
# "sheep".singluarize # => "sheep"
# "word".singluarize # => "word"
# "the blue mailmen".singularize # => "the blue mailman"
# "CamelOctopi".singularize # => "CamelOctopus"
def singularize
Inflector.singularize(self)
end
# By default, camelize converts strings to UpperCamelCase. If the argument to camelize
# is set to ":lower" then camelize produces lowerCamelCase.
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
# is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
#
# camelize will also convert '/' to '::' which is useful for converting paths to namespaces
# +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
#
# Examples
# "active_record".camelize #=> "ActiveRecord"
# "active_record".camelize(:lower) #=> "activeRecord"
# "active_record/errors".camelize #=> "ActiveRecord::Errors"
# "active_record/errors".camelize(:lower) #=> "activeRecord::Errors"
# "active_record".camelize # => "ActiveRecord"
# "active_record".camelize(:lower) # => "activeRecord"
# "active_record/errors".camelize # => "ActiveRecord::Errors"
# "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
def camelize(first_letter = :upper)
case first_letter
when :upper then Inflector.camelize(self, true)
@ -52,78 +50,72 @@ module ActiveSupport #:nodoc:
alias_method :camelcase, :camelize
# Capitalizes all the words and replaces some characters in the string to create
# a nicer looking title. Titleize is meant for creating pretty output. It is not
# a nicer looking title. +titleize+ is meant for creating pretty output. It is not
# used in the Rails internals.
#
# titleize is also aliased as as titlecase
# +titleize+ is also aliased as +titlecase+.
#
# Examples
# "man from the boondocks".titleize #=> "Man From The Boondocks"
# "x-men: the last stand".titleize #=> "X Men: The Last Stand"
# "man from the boondocks".titleize # => "Man From The Boondocks"
# "x-men: the last stand".titleize # => "X Men: The Last Stand"
def titleize
Inflector.titleize(self)
end
alias_method :titlecase, :titleize
# The reverse of +camelize+. Makes an underscored form from the expression in the string.
# The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
#
# Changes '::' to '/' to convert namespaces to paths.
# +underscore+ will also change '::' to '/' to convert namespaces to paths.
#
# Examples
# "ActiveRecord".underscore #=> "active_record"
# "ActiveRecord::Errors".underscore #=> active_record/errors
# "ActiveRecord".underscore # => "active_record"
# "ActiveRecord::Errors".underscore # => active_record/errors
def underscore
Inflector.underscore(self)
end
# Replaces underscores with dashes in the string.
#
# Example
# "puni_puni" #=> "puni-puni"
# "puni_puni" # => "puni-puni"
def dasherize
Inflector.dasherize(self)
end
# Removes the module part from the expression in the string
# Removes the module part from the constant expression in the string.
#
# Examples
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize #=> "Inflections"
# "Inflections".demodulize #=> "Inflections"
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
# "Inflections".demodulize # => "Inflections"
def demodulize
Inflector.demodulize(self)
end
# Create the name of a table like Rails does for models to table names. This method
# uses the pluralize method on the last word in the string.
# Creates the name of a table like Rails does for models to table names. This method
# uses the +pluralize+ method on the last word in the string.
#
# Examples
# "RawScaledScorer".tableize #=> "raw_scaled_scorers"
# "egg_and_ham".tableize #=> "egg_and_hams"
# "fancyCategory".tableize #=> "fancy_categories"
# "RawScaledScorer".tableize # => "raw_scaled_scorers"
# "egg_and_ham".tableize # => "egg_and_hams"
# "fancyCategory".tableize # => "fancy_categories"
def tableize
Inflector.tableize(self)
end
# Create a class name from a plural table name like Rails does for table names to models.
# Note that this returns a string and not a Class. (To convert to an actual class
# follow classify with constantize.)
# Note that this returns a string and not a class. (To convert to an actual class
# follow +classify+ with +constantize+.)
#
# Examples
# "egg_and_hams".classify #=> "EggAndHam"
# "posts".classify #=> "Post"
# "egg_and_hams".classify # => "EggAndHam"
# "posts".classify # => "Post"
#
# Singular names are not handled correctly
# "business".classify #=> "Busines"
# Singular names are not handled correctly.
#
# "business".classify # => "Busines"
def classify
Inflector.classify(self)
end
# Capitalizes the first word and turns underscores into spaces and strips _id.
# Like titleize, this is meant for creating pretty output.
# Capitalizes the first word, turns underscores into spaces, and strips '_id'.
# Like +titleize+, this is meant for creating pretty output.
#
# Examples
# "employee_salary" #=> "Employee salary"
# "author_id" #=> "Author"
# "employee_salary" # => "Employee salary"
# "author_id" # => "Author"
def humanize
Inflector.humanize(self)
end
@ -133,20 +125,20 @@ module ActiveSupport #:nodoc:
# the method should put '_' between the name and 'id'.
#
# Examples
# "Message".foreign_key #=> "message_id"
# "Message".foreign_key(false) #=> "messageid"
# "Admin::Post".foreign_key #=> "post_id"
# "Message".foreign_key # => "message_id"
# "Message".foreign_key(false) # => "messageid"
# "Admin::Post".foreign_key # => "post_id"
def foreign_key(separate_class_name_and_id_with_underscore = true)
Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
end
# Constantize tries to find a declared constant with the name specified
# +constantize+ tries to find a declared constant with the name specified
# in the string. It raises a NameError when the name is not in CamelCase
# or is not initialized.
#
# Examples
# "Module".constantize #=> Module
# "Class".constantize #=> Class
# "Module".constantize # => Module
# "Class".constantize # => Class
def constantize
Inflector.constantize(self)
end

View File

@ -27,7 +27,7 @@ module ActiveSupport #:nodoc:
# object. Interoperability problems can be resolved easily with a +to_s+ call.
#
# For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars and
# ActiveSupport::Multibyte::Handlers::UTF8Handler
# ActiveSupport::Multibyte::Handlers::UTF8Handler.
def chars
ActiveSupport::Multibyte::Chars.new(self)
end

View File

@ -43,18 +43,18 @@ module ActiveSupport #:nodoc:
end
end
# Returns the simultaneous time in Time.zone. Example:
# Returns the simultaneous time in Time.zone.
#
# Time.zone = 'Hawaii' # => 'Hawaii'
# Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
# Time.zone = 'Hawaii' # => 'Hawaii'
# Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
#
# This method is similar to Time#localtime, except that it uses Time.zone as the local zone
# instead of the operating system's time zone.
#
# You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
# and the conversion will be based on that zone instead of Time.zone. Example:
# and the conversion will be based on that zone instead of Time.zone.
#
# Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
# Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
def in_time_zone(zone = ::Time.zone)
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.send!(:get_zone, zone))
end

View File

@ -2,15 +2,18 @@ require 'zlib'
require 'stringio'
module ActiveSupport
# A convenient wrapper for the zlib standard library that allows compression/decompression of strings with gzip.
module Gzip
class Stream < StringIO
def close; rewind; end
end
# Decompresses a gzipped string.
def self.decompress(source)
Zlib::GzipReader.new(StringIO.new(source)).read
end
# Compresses a string using gzip.
def self.compress(source)
output = Stream.new
gz = Zlib::GzipWriter.new(output)

View File

@ -165,7 +165,7 @@ module Inflector
humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
end
# The reverse of +camelize+. Makes an underscored form from the expression in the string.
# The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
#
# Changes '::' to '/' to convert namespaces to paths.
#

View File

@ -1,5 +1,10 @@
class Date
def to_json(options = nil) #:nodoc:
# Returns a JSON string representing the date.
#
# ==== Example:
# Date.new(2005,2,1).to_json
# # => "2005/02/01"
def to_json(options = nil)
%("#{strftime("%Y/%m/%d")}")
end
end

View File

@ -1,5 +1,10 @@
class DateTime
def to_json(options = nil) #:nodoc:
# Returns a JSON string representing the datetime.
#
# ==== Example:
# DateTime.civil(2005,2,1,15,15,10).to_json
# # => "2005/02/01 15:15:10 +0000"
def to_json(options = nil)
%("#{strftime("%Y/%m/%d %H:%M:%S %z")}")
end
end

View File

@ -2,8 +2,8 @@ module Enumerable
# Returns a JSON string representing the enumerable. Any +options+
# given will be passed on to its elements. For example:
#
# users = User.find(:all)
# users.to_json(:only => :name)
# users = User.find(:all)
# # => users.to_json(:only => :name)
#
# will pass the <tt>:only => :name</tt> option to each user.
def to_json(options = {}) #:nodoc:

View File

@ -5,8 +5,7 @@ class Hash
# the hash keys. For example:
#
# { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json
#
# {"name": "Konata Izumi", 1: 2, "age": 16}
# # => {"name": "Konata Izumi", 1: 2, "age": 16}
#
# The keys in the JSON string are unordered due to the nature of hashes.
#
@ -14,12 +13,10 @@ class Hash
# attributes included, and will accept 1 or more hash keys to include/exclude.
#
# { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:only => [:name, 'age'])
#
# {"name": "Konata Izumi", "age": 16}
# # => {"name": "Konata Izumi", "age": 16}
#
# { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:except => 1)
#
# {"name": "Konata Izumi", "age": 16}
# # => {"name": "Konata Izumi", "age": 16}
#
# The +options+ also filter down to any hash values. This is particularly
# useful for converting hashes containing ActiveRecord objects or any object

View File

@ -1,5 +1,5 @@
class Object
# Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
# Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
def to_json(options = {})
ActiveSupport::JSON.encode(instance_values, options)
end

View File

@ -1,5 +1,10 @@
class Time
def to_json(options = nil) #:nodoc:
# Returns a JSON string representing the time.
#
# ==== Example:
# Time.utc(2005,2,1,15,15,10).to_json
# # => 2005/02/01 15:15:10 +0000"
def to_json(options = nil)
%("#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
end
end

View File

@ -18,6 +18,7 @@ class NilClass
methods.each { |method| @@method_class_map[method.to_sym] = class_name }
end
# Raises a RuntimeError when you attempt to call id on nil or a nil object.
def id
raise RuntimeError, "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id", caller
end
@ -27,6 +28,7 @@ class NilClass
raise_nil_warning_for @@method_class_map[method], method, caller
end
# Raises a NoMethodError when you attempt to call a method on nil, or a nil object.
def raise_nil_warning_for(class_name = nil, selector = nil, with_caller = nil)
message = "You have a nil object when you didn't expect it!"
message << "\nYou might have expected an instance of #{class_name}." if class_name

View File

@ -1,5 +1,7 @@
*SVN*
* Improve documentation. [Radar, Jan De Poorter, chuyeow, xaviershay, danger, miloops, Xavier Noria, Sunny Ripert]
* Added config.time_zone = 'UTC' as a commented-out option in the default environment.rb [Geoff Buesing]
* Adding rake tasks time:zones:all, time:zones:us and time:zones:local for finding time zone names for config.time_zone option [Geoff Buesing]

View File

@ -17,6 +17,12 @@ ActionController::Routing::Routes.draw do |map|
# Sample resource route with sub-resources:
# map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
# Sample resource route with more complex sub-resources
# map.resources :products do |products|
# products.resources :comments
# products.resources :sales, :collection => { :recent => :get }
# end
# Sample resource route within a namespace:
# map.namespace :admin do |admin|