Merge docrails:

commit e6afd8b273
Author: Xavier Noria <fxn@hashref.com>
Date:   Thu May 8 23:49:36 2008 +0200

    Overall documentation improvement and markup corrections. Zillion changes.

commit 2fead68b31
Author: Austin Putman <austin@emmanuel.local>
Date:   Wed May 7 19:35:46 2008 -0700

    Documented class methods on ActionController::Routing.  These are dangerous, and mostly used for testing.

commit f5b84182db
Author: Teflon Ted <github@rudiment.net>
Date:   Wed May 7 16:08:49 2008 -0400

    Added explanation about errant inflections not being patched in the future in order to avoid breaking legacy applications.

commit 370f4f5172
Author: Sunny Ripert <negatif@gmail.com>
Date:   Wed May 7 14:00:59 2008 +0200

    Applied list conventions in AR::Base

commit 5bd18429f0
Author: Sunny Ripert <negatif@gmail.com>
Date:   Wed May 7 13:53:35 2008 +0200

    Renamed Options list to Attributes list whenever they weren't option hashes in AR::Base

commit d912bd5672
Author: Yaroslav Markin <yaroslav@markin.net>
Date:   Wed May 7 13:50:28 2008 +0400

    Add a filter_parameter_logging usage hint to generated ApplicationController.
    This may help to remind the developer to filter sensitive information from application logs.
    Closes #11578

commit b243de0db3
Author: Jack Danger Canty <git@6brand.com>
Date:   Tue May 6 23:39:47 2008 -0700

    doc: disambiguating an example ActiveRecord class

commit f81d771f06
Author: Jack Danger Canty <git@6brand.com>
Date:   Tue May 6 23:35:05 2008 -0700

    doc: ActiveRecord::Reflection::AssociationReflection#through_reflection

    Added documentation demonstrating the use of #through_reflection for
    finding intervening reflection objects for HasManyThrough
    and HasOneThrough.

commit ae6b46f00b
Author: Cheah Chu Yeow <chuyeow@gmail.com>
Date:   Wed May 7 13:47:41 2008 +0800

    Document AttributeAssignmentError and MultiparameterAssignmentErrors.

commit 8f463550b5
Author: John Barnette <jbarnette@gmail.com>
Date:   Tue May 6 22:46:44 2008 -0700

    Killing/fixing a bunch of outdated language in the AR README.

commit aca44bcd92
Author: Cheah Chu Yeow <chuyeow@gmail.com>
Date:   Wed May 7 13:34:52 2008 +0800

    Make a note about ActiveResource::Timeouterror being raised when ARes calls timeout.

commit 284a930a93
Author: Jonathan Dance <jd@wuputah.com>
Date:   Tue May 6 14:58:26 2008 -0400

    improvements to the page caching docs

commit 9482da6213
Author: Sunny Ripert <negatif@gmail.com>
Date:   Mon May 5 18:13:40 2008 +0200

    validates_numericality_of() "integer" option really is "only_integer"

commit e9afd6790a
Author: Sunny Ripert <negatif@gmail.com>
Date:   Mon May 5 12:11:59 2008 +0200

    Harmonized hash notation in AR::Base

commit 67ebf14a91
Author: Sunny Ripert <negatif@gmail.com>
Date:   Mon May 5 12:06:19 2008 +0200

    Turned options into rdoc-lists in AR::Base

commit 0ec7c0a41d
Author: Marshall Huss <mwhuss@Macbook.local>
Date:   Sun May 4 23:21:33 2008 -0400

    Added information of how to set element_name in the case the user has a name confliction with an existing model

Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
This commit is contained in:
Pratik Naik 2008-05-09 10:38:02 +01:00
parent bfbf03ecee
commit dc4eec1129
34 changed files with 658 additions and 570 deletions

View File

@ -95,7 +95,7 @@ module ActionMailer #:nodoc:
#
# ActionMailer::Base.default_url_options[:host] = "example.com"
#
# This can also be set as a configuration option in <tt>environment.rb</tt>:
# This can also be set as a configuration option in <tt>config/environment.rb</tt>:
#
# config.action_mailer.default_url_options = { :host => "example.com" }
#
@ -204,22 +204,23 @@ module ActionMailer #:nodoc:
# Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
#
# * <tt>smtp_settings</tt> - Allows detailed configuration for <tt>:smtp</tt> delivery method:
# * <tt>:address</tt> Allows you to use a remote mail server. Just change it from its default "localhost" setting.
# * <tt>:port</tt> On the off chance that your mail server doesn't run on port 25, you can change it.
# * <tt>:domain</tt> If you need to specify a HELO domain, you can do it here.
# * <tt>:user_name</tt> If your mail server requires authentication, set the username in this setting.
# * <tt>:password</tt> If your mail server requires authentication, set the password in this setting.
# * <tt>:authentication</tt> If your mail server requires authentication, you need to specify the authentication type here.
# * <tt>:address</tt> - Allows you to use a remote mail server. Just change it from its default "localhost" setting.
# * <tt>:port</tt> - On the off chance that your mail server doesn't run on port 25, you can change it.
# * <tt>:domain</tt> - If you need to specify a HELO domain, you can do it here.
# * <tt>:user_name</tt> - If your mail server requires authentication, set the username in this setting.
# * <tt>:password</tt> - If your mail server requires authentication, set the password in this setting.
# * <tt>:authentication</tt> - If your mail server requires authentication, you need to specify the authentication type here.
# This is a symbol and one of <tt>:plain</tt>, <tt>:login</tt>, <tt>:cram_md5</tt>
#
# * <tt>sendmail_settings</tt> - Allows you to override options for the <tt>:sendmail</tt> delivery method
# * <tt>:location</tt> The location of the sendmail executable, defaults to "/usr/sbin/sendmail"
# * <tt>:arguments</tt> The command line arguments
# * <tt>raise_delivery_errors</tt> - whether or not errors should be raised if the email fails to be delivered.
# * <tt>:location</tt> - The location of the sendmail executable, defaults to "/usr/sbin/sendmail"
# * <tt>:arguments</tt> - The command line arguments
#
# * <tt>raise_delivery_errors</tt> - Whether or not errors should be raised if the email fails to be delivered.
#
# * <tt>delivery_method</tt> - Defines a delivery method. Possible values are <tt>:smtp</tt> (default), <tt>:sendmail</tt>, and <tt>:test</tt>.
#
# * <tt>perform_deliveries</tt> - Determines whether deliver_* methods are actually carried out. By default they are,
# * <tt>perform_deliveries</tt> - Determines whether <tt>deliver_*</tt> methods are actually carried out. By default they are,
# but this can be turned off to help functional testing.
#
# * <tt>deliveries</tt> - Keeps an array of all the emails sent out through the Action Mailer with <tt>delivery_method :test</tt>. Most useful
@ -406,7 +407,7 @@ module ActionMailer #:nodoc:
# templating language other than rhtml or rxml are supported.
# To use this, include in your template-language plugin's init
# code or on a per-application basis, this can be invoked from
# config/environment.rb:
# <tt>config/environment.rb</tt>:
#
# ActionMailer::Base.register_template_extension('haml')
def register_template_extension(extension)

View File

@ -21,11 +21,11 @@ module ActionController
# from the response HTML or elements selected by the enclosing assertion.
#
# In addition to HTML responses, you can make the following assertions:
# * #assert_select_rjs -- Assertions on HTML content of RJS update and
# * +assert_select_rjs+ - Assertions on HTML content of RJS update and
# insertion operations.
# * #assert_select_encoded -- Assertions on HTML encoded inside XML,
# * +assert_select_encoded+ - Assertions on HTML encoded inside XML,
# for example for dealing with feed item descriptions.
# * #assert_select_email -- Assertions on the HTML body of an e-mail.
# * +assert_select_email+ - Assertions on the HTML body of an e-mail.
#
# Also see HTML::Selector to learn how to use selectors.
module SelectorAssertions
@ -136,27 +136,27 @@ module ActionController
# === Equality Tests
#
# The equality test may be one of the following:
# * <tt>true</tt> -- Assertion is true if at least one element selected.
# * <tt>false</tt> -- Assertion is true if no element selected.
# * <tt>String/Regexp</tt> -- Assertion is true if the text value of at least
# * <tt>true</tt> - Assertion is true if at least one element selected.
# * <tt>false</tt> - Assertion is true if no element selected.
# * <tt>String/Regexp</tt> - Assertion is true if the text value of at least
# one element matches the string or regular expression.
# * <tt>Integer</tt> -- Assertion is true if exactly that number of
# * <tt>Integer</tt> - Assertion is true if exactly that number of
# elements are selected.
# * <tt>Range</tt> -- Assertion is true if the number of selected
# * <tt>Range</tt> - Assertion is true if the number of selected
# elements fit the range.
# If no equality test specified, the assertion is true if at least one
# element selected.
#
# To perform more than one equality tests, use a hash with the following keys:
# * <tt>:text</tt> -- Narrow the selection to elements that have this text
# * <tt>:text</tt> - Narrow the selection to elements that have this text
# value (string or regexp).
# * <tt>:html</tt> -- Narrow the selection to elements that have this HTML
# * <tt>:html</tt> - Narrow the selection to elements that have this HTML
# content (string or regexp).
# * <tt>:count</tt> -- Assertion is true if the number of selected elements
# * <tt>:count</tt> - Assertion is true if the number of selected elements
# is equal to this value.
# * <tt>:minimum</tt> -- Assertion is true if the number of selected
# * <tt>:minimum</tt> - Assertion is true if the number of selected
# elements is at least this value.
# * <tt>:maximum</tt> -- Assertion is true if the number of selected
# * <tt>:maximum</tt> - Assertion is true if the number of selected
# elements is at most this value.
#
# If the method is called with a block, once all equality tests are

View File

@ -159,28 +159,34 @@ module ActionController #:nodoc:
#
# Hello #{session[:person]}
#
# For removing objects from the session, you can either assign a single key to nil, like <tt>session[:person] = nil</tt>, or you can
# remove the entire session with reset_session.
# For removing objects from the session, you can either assign a single key to +nil+:
#
# Sessions are stored in a browser cookie that's cryptographically signed, but unencrypted, by default. This prevents
# the user from tampering with the session but also allows him to see its contents.
# # removes :person from session
# session[:person] = nil
#
# Do not put secret information in session!
# or you can remove the entire session with +reset_session+.
#
# Sessions are stored by default in a browser cookie that's cryptographically signed, but unencrypted.
# This prevents the user from tampering with the session but also allows him to see its contents.
#
# Do not put secret information in cookie-based sessions!
#
# Other options for session storage are:
#
# ActiveRecordStore: sessions are stored in your database, which works better than PStore with multiple app servers and,
# unlike CookieStore, hides your session contents from the user. To use ActiveRecordStore, set
# * ActiveRecordStore - Sessions are stored in your database, which works better than PStore with multiple app servers and,
# unlike CookieStore, hides your session contents from the user. To use ActiveRecordStore, set
#
# config.action_controller.session_store = :active_record_store
# config.action_controller.session_store = :active_record_store
#
# in your <tt>environment.rb</tt> and run <tt>rake db:sessions:create</tt>.
# in your <tt>config/environment.rb</tt> and run <tt>rake db:sessions:create</tt>.
#
# MemCacheStore: sessions are stored as entries in your memcached cache. Set the session store type in <tt>environment.rb</tt>:
# * MemCacheStore - Sessions are stored as entries in your memcached cache.
# Set the session store type in <tt>config/environment.rb</tt>:
#
# config.action_controller.session_store = :mem_cache_store
# config.action_controller.session_store = :mem_cache_store
#
# This assumes that memcached has been installed and configured properly. See the MemCacheStore docs for more information.
# This assumes that memcached has been installed and configured properly.
# See the MemCacheStore docs for more information.
#
# == Responses
#
@ -535,20 +541,20 @@ module ActionController #:nodoc:
#
# <tt>url_for</tt> is used to:
#
# All keys given to url_for are forwarded to the Route module, save for the following:
# * <tt>:anchor</tt> -- specifies the anchor name to be appended to the path. For example,
# All keys given to +url_for+ are forwarded to the Route module, save for the following:
# * <tt>:anchor</tt> - Specifies the anchor name to be appended to the path. For example,
# <tt>url_for :controller => 'posts', :action => 'show', :id => 10, :anchor => 'comments'</tt>
# will produce "/posts/show/10#comments".
# * <tt>:only_path</tt> -- if true, returns the relative URL (omitting the protocol, host name, and port) (<tt>false</tt> by default)
# * <tt>:trailing_slash</tt> -- if true, adds a trailing slash, as in "/archive/2005/". Note that this
# * <tt>:only_path</tt> - If true, returns the relative URL (omitting the protocol, host name, and port) (<tt>false</tt> by default).
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2005/". Note that this
# is currently not recommended since it breaks caching.
# * <tt>:host</tt> -- overrides the default (current) host if provided.
# * <tt>:protocol</tt> -- overrides the default (current) protocol if provided.
# * <tt>:port</tt> -- optionally specify the port to connect to.
# * <tt>:user</tt> -- Inline HTTP authentication (only plucked out if <tt>:password</tt> is also present).
# * <tt>:password</tt> -- Inline HTTP authentication (only plucked out if <tt>:user</tt> is also present).
# * <tt>:skip_relative_url_root</tt> -- if true, the url is not constructed using the relative_url_root of the request so the path
# will include the web server relative installation directory.
# * <tt>:host</tt> - Overrides the default (current) host if provided.
# * <tt>:protocol</tt> - Overrides the default (current) protocol if provided.
# * <tt>:port</tt> - Optionally specify the port to connect to.
# * <tt>:user</tt> - Inline HTTP authentication (only plucked out if <tt>:password</tt> is also present).
# * <tt>:password</tt> - Inline HTTP authentication (only plucked out if <tt>:user</tt> is also present).
# * <tt>:skip_relative_url_root</tt> - If true, the url is not constructed using the +relative_url_root+
# of the request so the path will include the web server relative installation directory.
#
# The URL is generated from the remaining keys in the hash. A URL contains two key parts: the <base> and a query string.
# Routes composes a query string as the key/value pairs not included in the <base>.

View File

@ -20,7 +20,8 @@ module ActionController #:nodoc:
#
# == Caching stores
#
# All the caching stores from ActiveSupport::Cache is available to be used as backends for Action Controller caching.
# All the caching stores from ActiveSupport::Cache is available to be used as backends for Action Controller caching. This setting only
# affects action and fragment caching as page caching is always written to disk.
#
# Configuration examples (MemoryStore is the default):
#

View File

@ -4,23 +4,24 @@ require 'uri'
module ActionController #:nodoc:
module Caching
# Page caching is an approach to caching where the entire action output of is stored as a HTML file that the web server
# can serve without going through the Action Pack. This can be as much as 100 times faster than going through the process of dynamically
# generating the content. Unfortunately, this incredible speed-up is only available to stateless pages where all visitors
# are treated the same. Content management systems -- including weblogs and wikis -- have many pages that are a great fit
# for this approach, but account-based systems where people log in and manipulate their own data are often less likely candidates.
# can serve without going through Action Pack. This is the fastest way to cache your content as opposed to going dynamically
# through the process of generating the content. Unfortunately, this incredible speed-up is only available to stateless pages
# where all visitors are treated the same. Content management systems -- including weblogs and wikis -- have many pages that are
# a great fit for this approach, but account-based systems where people log in and manipulate their own data are often less
# likely candidates.
#
# Specifying which actions to cache is done through the <tt>caches</tt> class method:
# Specifying which actions to cache is done through the <tt>caches_page</tt> class method:
#
# class WeblogController < ActionController::Base
# caches_page :show, :new
# end
#
# This will generate cache files such as weblog/show/5 and weblog/new, which match the URLs used to trigger the dynamic
# generation. This is how the web server is able pick up a cache file when it exists and otherwise let the request pass on to
# the Action Pack to generate it.
# This will generate cache files such as <tt>weblog/show/5.html</tt> and <tt>weblog/new.html</tt>,
# which match the URLs used to trigger the dynamic generation. This is how the web server is able
# pick up a cache file when it exists and otherwise let the request pass on to Action Pack to generate it.
#
# Expiration of the cache is handled by deleting the cached file, which results in a lazy regeneration approach where the cache
# is not restored before another hit is made against it. The API for doing so mimics the options from url_for and friends:
# is not restored before another hit is made against it. The API for doing so mimics the options from +url_for+ and friends:
#
# class WeblogController < ActionController::Base
# def update
@ -35,13 +36,17 @@ module ActionController #:nodoc:
#
# == Setting the cache directory
#
# The cache directory should be the document root for the web server and is set using Base.page_cache_directory = "/document/root".
# For Rails, this directory has already been set to Rails.public_path (which is usually set to RAILS_ROOT + "/public").
# The cache directory should be the document root for the web server and is set using <tt>Base.page_cache_directory = "/document/root"</tt>.
# For Rails, this directory has already been set to Rails.public_path (which is usually set to <tt>RAILS_ROOT + "/public"</tt>). Changing
# this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your
# web server to look in the new location for cached files.
#
# == Setting the cache extension
#
# By default, the cache extension is .html, which makes it easy for the cached files to be picked up by the web server. If you want
# something else, like .php or .shtml, just set Base.page_cache_extension.
# Most Rails requests do not have an extension, such as <tt>/weblog/new</tt>. In these cases, the page caching mechanism will add one in
# order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is <tt>.html</tt>.
# If you want something else, like <tt>.php</tt> or <tt>.shtml</tt>, just set Base.page_cache_extension. In cases where a request already has an
# extension, such as <tt>.xml</tt> or <tt>.rss</tt>, page caching will not add an extension. This allows it to work well with RESTful apps.
module Pages
def self.included(base) #:nodoc:
base.extend(ClassMethods)

View File

@ -47,25 +47,27 @@ module ActionController
# Constructs a call to a named RESTful route for the given record and returns the
# resulting URL string. For example:
#
# polymorphic_url(post)
# # calls post_url(post) #=> "http://example.com/posts/1"
# # calls post_url(post)
# polymorphic_url(post) # => "http://example.com/posts/1"
#
# ==== Options
# * <tt>:action</tt> -- specifies the action prefix for the named route:
# <tt>:new</tt>, <tt>:edit</tt> or <tt>:formatted</tt>. Default is no prefix.
# * <tt>:routing_type</tt> -- <tt>:path</tt> or <tt>:url</tt> (default <tt>:url</tt>).
#
# * <tt>:action</tt> - Specifies the action prefix for the named route:
# <tt>:new</tt>, <tt>:edit</tt>, or <tt>:formatted</tt>. Default is no prefix.
# * <tt>:routing_type</tt> - Allowed values are <tt>:path</tt> or <tt>:url</tt>.
# Default is <tt>:url</tt>.
#
# ==== Examples
#
# # an Article record
# polymorphic_url(record) #-> article_url(record)
# polymorphic_url(record) # same as article_url(record)
#
# # a Comment record
# polymorphic_url(record) #-> comment_url(record)
# polymorphic_url(record) # same as comment_url(record)
#
# # it recognizes new records and maps to the collection
# record = Comment.new
# polymorphic_url(record) #-> comments_url()
# polymorphic_url(record) # same as comments_url()
#
def polymorphic_url(record_or_hash_or_array, options = {})
if record_or_hash_or_array.kind_of?(Array)

View File

@ -69,10 +69,10 @@ module ActionController #:nodoc:
#
# Valid Options:
#
# * <tt>:only/:except</tt> - passed to the <tt>before_filter</tt> call. Set which actions are verified.
# * <tt>:only/:except</tt> - Passed to the <tt>before_filter</tt> call. Set which actions are verified.
# * <tt>:secret</tt> - Custom salt used to generate the <tt>form_authenticity_token</tt>.
# Leave this off if you are using the cookie session store.
# * <tt>:digest</tt> - Message digest used for hashing. Defaults to 'SHA1'
# * <tt>:digest</tt> - Message digest used for hashing. Defaults to 'SHA1'.
def protect_from_forgery(options = {})
self.request_forgery_protection_token ||= :authenticity_token
before_filter :verify_authenticity_token, :only => options.delete(:only), :except => options.delete(:except)

View File

@ -236,27 +236,27 @@ module ActionController
# 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.
# 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>
# or <tt>:any</tt> if the method does not matter. These routes map to a URL like /messages/rss, with a route of rss_messages_url.
# * <tt>:member</tt> - same as <tt>:collection</tt>, but for actions that operate on a specific member.
# * <tt>:new</tt> - same as <tt>:collection</tt>, but for actions that operate on the new resource action.
# * <tt>:controller</tt> - specify the controller name for the routes.
# * <tt>:singular</tt> - specify the singular name used in the member routes.
# * <tt>:requirements</tt> - set custom routing parameter requirements.
# * <tt>:conditions</tt> - specify custom routing recognition conditions. Resources sets the <tt>:method</tt> value for the method-specific routes.
# * <tt>:as</tt> - specify a different resource name to use in the URL path. For example:
# or <tt>:any</tt> if the method does not matter. These routes map to a URL like /messages/rss, with a route of +rss_messages_url+.
# * <tt>:member</tt> - Same as <tt>:collection</tt>, but for actions that operate on a specific member.
# * <tt>:new</tt> - Same as <tt>:collection</tt>, but for actions that operate on the new resource action.
# * <tt>:controller</tt> - Specify the controller name for the routes.
# * <tt>:singular</tt> - Specify the singular name used in the member routes.
# * <tt>:requirements</tt> - Set custom routing parameter requirements.
# * <tt>:conditions</tt> - Specify custom routing recognition conditions. Resources sets the <tt>:method</tt> value for the method-specific routes.
# * <tt>:as</tt> - Specify a different resource name to use in the URL path. For example:
# # products_path == '/productos'
# map.resources :products, :as => 'productos' do |product|
# # product_reviews_path(product) == '/productos/1234/comentarios'
# product.resources :product_reviews, :as => 'comentarios'
# end
#
# * <tt>:has_one</tt> - specify nested resources, this is a shorthand for mapping singleton resources beneath the current.
# * <tt>:has_many</tt> - same has <tt>:has_one</tt>, but for plural resources.
# * <tt>:has_one</tt> - Specify nested resources, this is a shorthand for mapping singleton resources beneath the current.
# * <tt>:has_many</tt> - Same has <tt>:has_one</tt>, but for plural resources.
#
# You may directly specify the routing association with has_one and has_many like:
# You may directly specify the routing association with +has_one+ and +has_many+ like:
#
# map.resources :notes, :has_one => :author, :has_many => [:comments, :attachments]
#
@ -268,14 +268,14 @@ module ActionController
# notes.resources :attachments
# end
#
# * <tt>:path_names</tt> - specify different names for the 'new' and 'edit' actions. For example:
# * <tt>:path_names</tt> - Specify different names for the 'new' and 'edit' actions. For example:
# # new_products_path == '/productos/nuevo'
# map.resources :products, :as => 'productos', :path_names => { :new => 'nuevo', :edit => 'editar' }
#
# You can also set default action names from an environment, like this:
# config.action_controller.resources_path_names = { :new => 'nuevo', :edit => 'editar' }
#
# * <tt>:path_prefix</tt> - set a prefix to the routes with required route variables.
# * <tt>:path_prefix</tt> - Set a prefix to the routes with required route variables.
#
# Weblog comments usually belong to a post, so you might use resources like:
#
@ -296,7 +296,7 @@ module ActionController
# article_comments_url(:article_id => @article)
# article_comment_url(:article_id => @article, :id => @comment)
#
# * <tt>:name_prefix</tt> - define a prefix for all generated routes, usually ending in an underscore.
# * <tt>:name_prefix</tt> - Define a prefix for all generated routes, usually ending in an underscore.
# Use this if you have named routes that may clash.
#
# map.resources :tags, :path_prefix => '/books/:book_id', :name_prefix => 'book_'
@ -343,7 +343,7 @@ module ActionController
# # --> GET /categories/7/messages/1
# # has named route "category_message"
#
# The #resources method sets HTTP method restrictions on the routes it generates. For example, making an
# The +resources+ method sets HTTP method restrictions on the routes it generates. For example, making an
# HTTP POST on <tt>new_message_url</tt> will raise a RoutingError exception. The default route in
# <tt>config/routes.rb</tt> overrides this and allows invalid HTTP methods for resource routes.
def resources(*entities, &block)

View File

@ -15,7 +15,7 @@ module ActionController
# The routing module provides URL rewriting in native Ruby. It's a way to
# redirect incoming requests to controllers and actions. This replaces
# mod_rewrite rules. Best of all, Rails' Routing works with any web server.
# Routes are defined in routes.rb in your RAILS_ROOT/config directory.
# Routes are defined in <tt>config/routes.rb</tt>.
#
# Consider the following route, installed by Rails when you generate your
# application:
@ -53,7 +53,7 @@ module ActionController
# == Route priority
#
# Not all routes are created equally. Routes have priority defined by the
# order of appearance of the routes in the routes.rb file. The priority goes
# order of appearance of the routes in the <tt>config/routes.rb</tt> file. The priority goes
# from top to bottom. The last route in that file is at the lowest priority
# and will be applied last. If no route matches, 404 is returned.
#
@ -118,7 +118,7 @@ module ActionController
# root_url # => 'http://www.example.com/'
# root_path # => ''
#
# You can also specify an already-defined named route in your map.root call:
# You can also specify an already-defined named route in your <tt>map.root</tt> call:
#
# # In routes.rb
# map.new_session :controller => 'sessions', :action => 'new'
@ -217,7 +217,7 @@ module ActionController
# ActionController::Routing::Routes.reload
#
# This will clear all named routes and reload routes.rb if the file has been modified from
# last load. To absolutely force reloading, use +reload!+.
# last load. To absolutely force reloading, use <tt>reload!</tt>.
#
# == Testing Routes
#
@ -277,6 +277,9 @@ module ActionController
end
class << self
# Expects an array of controller names as the first argument.
# Executes the passed block with only the named controllers named available.
# This method is used in internal Rails testing.
def with_controllers(names)
prior_controllers = @possible_controllers
use_controllers! names
@ -285,6 +288,10 @@ module ActionController
use_controllers! prior_controllers
end
# Returns an array of paths, cleaned of double-slashes and relative path references.
# * "\\\" and "//" become "\\" or "/".
# * "/foo/bar/../config" becomes "/foo/config".
# The returned array is sorted by length, descending.
def normalize_paths(paths)
# do the hokey-pokey of path normalization...
paths = paths.collect do |path|
@ -303,6 +310,7 @@ module ActionController
paths = paths.uniq.sort_by { |path| - path.length }
end
# Returns the array of controller names currently available to ActionController::Routing.
def possible_controllers
unless @possible_controllers
@possible_controllers = []
@ -327,10 +335,28 @@ module ActionController
@possible_controllers
end
# Replaces the internal list of controllers available to ActionController::Routing with the passed argument.
# ActionController::Routing.use_controllers!([ "posts", "comments", "admin/comments" ])
def use_controllers!(controller_names)
@possible_controllers = controller_names
end
# Returns a controller path for a new +controller+ based on a +previous+ controller path.
# Handles 4 scenarios:
#
# * stay in the previous controller:
# controller_relative_to( nil, "groups/discussion" ) # => "groups/discussion"
#
# * stay in the previous namespace:
# controller_relative_to( "posts", "groups/discussion" ) # => "groups/posts"
#
# * forced move to the root namespace:
# controller_relative_to( "/posts", "groups/discussion" ) # => "posts"
#
# * previous namespace is root:
# controller_relative_to( "posts", "anything_with_no_slashes" ) # =>"posts"
#
def controller_relative_to(controller, previous)
if controller.nil? then previous
elsif controller[0] == ?/ then controller[1..-1]
@ -344,6 +370,7 @@ module ActionController
Routes = RouteSet.new
::Inflector.module_eval do
# Ensures that routes are reloaded when Rails inflections are updated.
def inflections_with_route_reloading(&block)
returning(inflections_without_route_reloading(&block)) {
ActionController::Routing::Routes.reload! if block_given?

View File

@ -13,7 +13,7 @@ class CGI
# A session store backed by an Active Record class. A default class is
# provided, but any object duck-typing to an Active Record +Session+ class
# provided, but any object duck-typing to an Active Record Session class
# with text +session_id+ and +data+ attributes is sufficient.
#
# The default assumes a +sessions+ tables with columns:
@ -26,13 +26,13 @@ class CGI
# ActionController::SessionOverflowError will be raised.
#
# You may configure the table name, primary key, and data column.
# For example, at the end of config/environment.rb:
# For example, at the end of <tt>config/environment.rb</tt>:
# CGI::Session::ActiveRecordStore::Session.table_name = 'legacy_session_table'
# CGI::Session::ActiveRecordStore::Session.primary_key = 'session_id'
# CGI::Session::ActiveRecordStore::Session.data_column_name = 'legacy_session_data'
# Note that setting the primary key to the session_id frees you from
# having a separate id column if you don't want it. However, you must
# set session.model.id = session.session_id by hand! A before_filter
# Note that setting the primary key to the +session_id+ frees you from
# having a separate +id+ column if you don't want it. However, you must
# set <tt>session.model.id = session.session_id</tt> by hand! A before filter
# on ApplicationController is a good place.
#
# Since the default class is a simple Active Record, you get timestamps
@ -42,7 +42,7 @@ class CGI
# You may provide your own session class implementation, whether a
# feature-packed Active Record or a bare-metal high-performance SQL
# store, by setting
# +CGI::Session::ActiveRecordStore.session_class = MySessionClass+
# CGI::Session::ActiveRecordStore.session_class = MySessionClass
# You must implement these methods:
# self.find_by_session_id(session_id)
# initialize(hash_of_session_id_and_data)
@ -154,8 +154,13 @@ class CGI
# The database connection, table name, and session id and data columns
# are configurable class attributes. Marshaling and unmarshaling
# are implemented as class methods that you may override. By default,
# marshaling data is +ActiveSupport::Base64.encode64(Marshal.dump(data))+ and
# unmarshaling data is +Marshal.load(ActiveSupport::Base64.decode64(data))+.
# marshaling data is
#
# ActiveSupport::Base64.encode64(Marshal.dump(data))
#
# and unmarshaling data is
#
# Marshal.load(ActiveSupport::Base64.decode64(data))
#
# This marshaling behavior is intended to store the widest range of
# binary session data in a +text+ column. For higher performance,

View File

@ -29,16 +29,16 @@ module ActionController
# Generate a url based on the options provided, default_url_options and the
# routes defined in routes.rb. The following options are supported:
#
# * <tt>:only_path</tt> If true, the relative url is returned. Defaults to +false+.
# * <tt>:protocol</tt> The protocol to connect to. Defaults to 'http'.
# * <tt>:host</tt> Specifies the host the link should be targetted at.
# * <tt>:only_path</tt> - If true, the relative url is returned. Defaults to +false+.
# * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
# * <tt>:host</tt> - Specifies the host the link should be targetted at.
# If <tt>:only_path</tt> is false, this option must be
# provided either explicitly, or via +default_url_options+.
# * <tt>:port</tt> Optionally specify the port to connect to.
# * <tt>:anchor</tt> An anchor name to be appended to the path.
# * <tt>:skip_relative_url_root</tt> If true, the url is not constructed using the
# * <tt>:port</tt> - Optionally specify the port to connect to.
# * <tt>:anchor</tt> - An anchor name to be appended to the path.
# * <tt>:skip_relative_url_root</tt> - If true, the url is not constructed using the
# +relative_url_root+ set in ActionController::AbstractRequest.relative_url_root.
# * <tt>:trailing_slash</tt> If true, adds a trailing slash, as in "/archive/2009/"
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
#
# Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
# +url_for+ is forwarded to the Routes module.

View File

@ -5,9 +5,9 @@ module ActionView #:nodoc:
class MissingTemplate < ActionViewError #:nodoc:
end
# Action View templates can be written in three ways. If the template file has a +.erb+ (or +.rhtml+) extension then it uses a mixture of ERb
# (included in Ruby) and HTML. If the template file has a +.builder+ (or +.rxml+) extension then Jim Weirich's Builder::XmlMarkup library is used.
# If the template file has a +.rjs+ extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.
# Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb
# (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used.
# If the template file has a <tt>.rjs</tt> extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.
#
# = ERb
#
@ -24,7 +24,7 @@ module ActionView #:nodoc:
#
# Hi, Mr. <% puts "Frodo" %>
#
# If you absolutely must write from within a function, you can use the TextHelper#concat
# If you absolutely must write from within a function, you can use the TextHelper#concat.
#
# <%- and -%> suppress leading and trailing whitespace, including the trailing newline, and can be used interchangeably with <% and %>.
#
@ -46,7 +46,7 @@ module ActionView #:nodoc:
# <% @page_title = "A Wonderful Hello" %>
# <%= render "shared/header" %>
#
# Now the header can pick up on the @page_title variable and use it for outputting a title tag:
# Now the header can pick up on the <tt>@page_title</tt> variable and use it for outputting a title tag:
#
# <title><%= @page_title %></title>
#
@ -56,7 +56,7 @@ module ActionView #:nodoc:
#
# <%= render "shared/header", { :headline => "Welcome", :person => person } %>
#
# These can now be accessed in shared/header with:
# These can now be accessed in <tt>shared/header</tt> with:
#
# Headline: <%= headline %>
# First name: <%= person.first_name %>
@ -77,13 +77,13 @@ module ActionView #:nodoc:
#
# == Builder
#
# Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An +XmlMarkup+ object
# named +xml+ is automatically made available to templates with a +.builder+ extension.
# Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object
# named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension.
#
# Here are some basic examples:
#
# xml.em("emphasized") # => <em>emphasized</em>
# xml.em { xml.b("emph & bold") } # => <em><b>emph &amp; bold</b></em>
# xml.em { xml.b("emph & bold") } # => <em><b>emph &amp; bold</b></em>
# xml.a("A Link", "href"=>"http://onestepback.org") # => <a href="http://onestepback.org">A Link</a>
# xml.target("name"=>"compile", "option"=>"fast") # => <target option="fast" name="compile"\>
# # NOTE: order of attributes is not specified.
@ -130,18 +130,18 @@ module ActionView #:nodoc:
#
# == JavaScriptGenerator
#
# JavaScriptGenerator templates end in +.rjs+. Unlike conventional templates which are used to
# JavaScriptGenerator templates end in <tt>.rjs</tt>. Unlike conventional templates which are used to
# render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to
# modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax
# and make updates to the page where the request originated from.
#
# An instance of the JavaScriptGenerator object named +page+ is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.
#
# When an .rjs action is called with +link_to_remote+, the generated JavaScript is automatically evaluated. Example:
# When an <tt>.rjs</tt> action is called with +link_to_remote+, the generated JavaScript is automatically evaluated. Example:
#
# link_to_remote :url => {:action => 'delete'}
#
# The subsequently rendered +delete.rjs+ might look like:
# The subsequently rendered <tt>delete.rjs</tt> might look like:
#
# page.replace_html 'sidebar', :partial => 'sidebar'
# page.remove "person-#{@person.id}"

View File

@ -316,12 +316,12 @@ module ActionView
# Creates a submit button with the text <tt>value</tt> as the caption.
#
# ==== Options
# * <tt>:confirm => 'question?'</tt> -- This will add a JavaScript confirm
# * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
# prompt with the question specified. If the user accepts, the form is
# processed normally, otherwise no action is taken.
# * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
# * <tt>:disabled</tt> - If true, the user will not be able to use this input.
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a disabled version
# of the submit button when the form is submitted.
# of the submit button when the form is submitted.
# * Any other key creates standard HTML options for the tag.
#
# ==== Examples

View File

@ -631,6 +631,27 @@ module ActionView
# render(:update) { |page| page.update_time }
# end
#
# Calls to JavaScriptGenerator not matching a helper method below
# generate a proxy to the JavaScript Class named by the method called.
#
# Examples:
#
# # Generates:
# # Foo.init();
# update_page do |page|
# page.foo.init
# end
#
# # Generates:
# # Event.observe('one', 'click', function () {
# # $('two').show();
# # });
# update_page do |page|
# page.event.observe('one', 'click') do |p|
# p[:two].show
# end
# end
#
# You can also use PrototypeHelper#update_page_tag instead of
# PrototypeHelper#update_page to wrap the generated JavaScript in a
# <script> tag.
@ -855,12 +876,21 @@ module ActionView
#
# Examples:
#
# # Generates: Element.replace(my_element, "My content to replace with.")
# page.call 'Element.replace', 'my_element', "My content to replace with."
#
# # Generates: alert('My message!')
# page.call 'alert', 'My message!'
#
# # Generates: Element.replace(my_element, "My content to replace with.")
# page.call 'Element.replace', 'my_element', "My content to replace with."
#
# # Generates: alert('My message!')
# page.call 'alert', 'My message!'
#
# # Generates:
# # my_method(function() {
# # $("one").show();
# # $("two").hide();
# # });
# page.call(:my_method) do |p|
# p[:one].show
# p[:two].hide
# end
def call(function, *arguments, &block)
record "#{function}(#{arguments_for_call(arguments, block)})"
end

View File

@ -19,15 +19,15 @@ module ActionView
# need an unescaped url, pass <tt>:escape => false</tt> in the +options+.
#
# ==== Options
# * <tt>:anchor</tt> -- specifies the anchor name to be appended to the path.
# * <tt>:only_path</tt> -- if true, returns the relative URL (omitting the protocol, host name, and port) (<tt>true</tt> by default unless <tt>:host</tt> is specified)
# * <tt>:trailing_slash</tt> -- if true, adds a trailing slash, as in "/archive/2005/". Note that this
# * <tt>:anchor</tt> - Specifies the anchor name to be appended to the path.
# * <tt>:only_path</tt> - If true, returns the relative URL (omitting the protocol, host name, and port) (<tt>true</tt> by default unless <tt>:host</tt> is specified).
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2005/". Note that this
# is currently not recommended since it breaks caching.
# * <tt>:host</tt> -- overrides the default (current) host if provided
# * <tt>:protocol</tt> -- overrides the default (current) protocol if provided
# * <tt>:user</tt> -- Inline HTTP authentication (only plucked out if <tt>:password</tt> is also present)
# * <tt>:password</tt> -- Inline HTTP authentication (only plucked out if <tt>:user</tt> is also present)
# * <tt>:escape</tt> -- Determines whether the returned URL will be HTML escaped or not (<tt>true</tt> by default)
# * <tt>:host</tt> - Overrides the default (current) host if provided.
# * <tt>:protocol</tt> - Overrides the default (current) protocol if provided.
# * <tt>:user</tt> - Inline HTTP authentication (only plucked out if <tt>:password</tt> is also present).
# * <tt>:password</tt> - Inline HTTP authentication (only plucked out if <tt>:user</tt> is also present).
# * <tt>:escape</tt> - Determines whether the returned URL will be HTML escaped or not (<tt>true</tt> by default).
#
# ==== Relying on named routes
#
@ -91,14 +91,14 @@ module ActionView
# a name, the link itself will become the name.
#
# ==== Options
# * <tt>:confirm => 'question?'</tt> -- This will add a JavaScript confirm
# * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
# prompt with the question specified. If the user accepts, the link is
# processed normally, otherwise no action is taken.
# * <tt>:popup => true || array of window options</tt> -- This will force the
# * <tt>:popup => true || array of window options</tt> - This will force the
# link to open in a popup window. By passing true, a default browser window
# will be opened with the URL. You can also specify an array of options
# that are passed-thru to JavaScripts window.open method.
# * <tt>:method => symbol of HTTP verb</tt> -- This modifier will dynamically
# * <tt>:method => symbol of HTTP verb</tt> - This modifier will dynamically
# create an HTML form and immediately submit the form for processing using
# the HTTP verb specified. Useful for having links perform a POST operation
# in dangerous actions like deleting a record (which search bots can follow
@ -178,9 +178,9 @@ module ActionView
# The +options+ hash accepts the same options at url_for.
#
# There are a few special +html_options+:
# * <tt>:method</tt> -- specifies the anchor name to be appended to the path.
# * <tt>:disabled</tt> -- specifies the anchor name to be appended to the path.
# * <tt>:confirm</tt> -- This will add a JavaScript confirm
# * <tt>:method</tt> - Specifies the anchor name to be appended to the path.
# * <tt>:disabled</tt> - Specifies the anchor name to be appended to the path.
# * <tt>:confirm</tt> - This will add a JavaScript confirm
# prompt with the question specified. If the user accepts, the link is
# processed normally, otherwise no action is taken.
#

View File

@ -25,7 +25,7 @@ module ActiveModel
#
# Configuration options:
# * <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>: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.

View File

@ -15,17 +15,17 @@ module ActiveModel
# 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 <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>: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.

View File

@ -169,10 +169,10 @@ A short rundown of the major features:
class AddSystemSettings < ActiveRecord::Migration
def self.up
create_table :system_settings do |t|
t.string :name
t.string :label
t.text :value
t.string :type
t.string :name
t.string :label
t.text :value
t.string :type
t.integer :position
end
@ -289,16 +289,6 @@ Bi-directional associations thanks to the "belongs_to" macro
thirty_seven_signals.firm.nil? # true
== Examples
Active Record ships with a couple of examples that should give you a good feel for
operating usage. Be sure to edit the <tt>examples/shared_setup.rb</tt> file for your
own database before running the examples. Possibly also the table definition SQL in
the examples themselves.
It's also highly recommended to have a look at the unit tests. Read more in link:files/RUNNING_UNIT_TESTS.html
== Philosophy
Active Record attempts to provide a coherent wrapper as a solution for the inconvenience that is
@ -336,7 +326,7 @@ then use:
% [sudo] gem install activerecord-1.10.0.gem
You can also install Active Record the old-fashion way with the following command:
You can also install Active Record the old-fashioned way with the following command:
% [sudo] ruby install.rb
@ -357,5 +347,5 @@ RubyForge page at http://rubyforge.org/projects/activerecord. And as Jim from Ra
remember to update the corresponding unit tests. If fact, I prefer
new feature to be submitted in the form of new unit tests.
For other information, feel free to ask on the ruby-talk mailing list
(which is mirrored to comp.lang.ruby) or contact mailto:david@loudthinking.com.
For other information, feel free to ask on the rubyonrails-talk
(http://groups.google.com/group/rubyonrails-talk) mailing list.

View File

@ -110,7 +110,7 @@ module ActiveRecord
#
# Don't create associations that have the same name as instance methods of ActiveRecord::Base. Since the association
# adds a method with that name to its model, it will override the inherited method and break things.
# For instance, #attributes and #connection would be bad choices for association names.
# For instance, +attributes+ and +connection+ would be bad choices for association names.
#
# == Auto-generated methods
#
@ -258,7 +258,7 @@ module ActiveRecord
# order to update their primary keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
# * If either of these saves fail (due to one of the objects being invalid) the assignment statement returns +false+ and the assignment
# is cancelled.
# * If you wish to assign an object to a +has_one+ association without saving it, use the <tt>#association.build</tt> method (documented below).
# * If you wish to assign an object to a +has_one+ association without saving it, use the <tt>association.build</tt> method (documented below).
# * Assigning an object to a +belongs_to+ association does not save the object, since the foreign key field belongs on the parent. It
# does not save the parent either.
#
@ -266,8 +266,8 @@ module ActiveRecord
#
# * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically saves that object, except if the parent object
# (the owner of the collection) is not yet stored in the database.
# * If saving any of the objects being added to a collection (via <tt>#push</tt> or similar) fails, then <tt>#push</tt> returns +false+.
# * You can add an object to a collection without automatically saving it by using the <tt>#collection.build</tt> method (documented below).
# * If saving any of the objects being added to a collection (via <tt>push</tt> or similar) fails, then <tt>push</tt> returns +false+.
# * You can add an object to a collection without automatically saving it by using the <tt>collection.build</tt> method (documented below).
# * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically saved when the parent is saved.
#
# === Association callbacks
@ -504,8 +504,8 @@ module ActiveRecord
#
# Address.find(:all, :include => :addressable) # INVALID
#
# will raise <tt>ActiveRecord::EagerLoadPolymorphicError</tt>. The reason is that the parent model's type
# is a column value so its corresponding table name cannot be put in the FROM/JOIN clauses of that early query.
# will raise ActiveRecord::EagerLoadPolymorphicError. The reason is that the parent model's type
# is a column value so its corresponding table name cannot be put in the +FROM+/+JOIN+ clauses of that early query.
#
# In versions greater than 2.0.2 eager loading in polymorphic associations is supported
# thanks to a change in the overall preloading strategy.
@ -575,7 +575,7 @@ module ActiveRecord
# end
# end
#
# When <tt>Firm#clients</tt> is called, it will in turn call <tt>MyApplication::Business::Company.find(firm.id)</tt>. If you want to associate
# When Firm#clients is called, it will in turn call <tt>MyApplication::Business::Company.find(firm.id)</tt>. If you want to associate
# with a class in another module scope, this can be done by specifying the complete class name. Example:
#
# module MyApplication
@ -603,28 +603,28 @@ module ActiveRecord
# Adds the following methods for retrieval and query of collections of associated objects:
# +collection+ is replaced with the symbol passed as the first argument, so
# <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
# * <tt>collection(force_reload = false)</tt> - returns an array of all the associated objects.
# * <tt>collection(force_reload = false)</tt> - Returns an array of all the associated objects.
# An empty array is returned if none are found.
# * <tt>collection<<(object, ...)</tt> - adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
# * <tt>collection.delete(object, ...)</tt> - removes one or more objects from the collection by setting their foreign keys to NULL.
# * <tt>collection<<(object, ...)</tt> - Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
# * <tt>collection.delete(object, ...)</tt> - Removes one or more objects from the collection by setting their foreign keys to +NULL+.
# This will also destroy the objects if they're declared as +belongs_to+ and dependent on this model.
# * <tt>collection=objects</tt> - replaces the collections content by deleting and adding objects as appropriate.
# * <tt>collection_singular_ids</tt> - returns an array of the associated objects' ids
# * <tt>collection_singular_ids=ids</tt> - replace the collection with the objects identified by the primary keys in +ids+
# * <tt>collection.clear</tt> - removes every object from the collection. This destroys the associated objects if they
# * <tt>collection=objects</tt> - Replaces the collections content by deleting and adding objects as appropriate.
# * <tt>collection_singular_ids</tt> - Returns an array of the associated objects' ids
# * <tt>collection_singular_ids=ids</tt> - Replace the collection with the objects identified by the primary keys in +ids+
# * <tt>collection.clear</tt> - Removes every object from the collection. This destroys the associated objects if they
# are associated with <tt>:dependent => :destroy</tt>, deletes them directly from the database if <tt>:dependent => :delete_all</tt>,
# otherwise sets their foreign keys to NULL.
# * <tt>collection.empty?</tt> - returns +true+ if there are no associated objects.
# * <tt>collection.size</tt> - returns the number of associated objects.
# * <tt>collection.find</tt> - finds an associated object according to the same rules as Base.find.
# * <tt>collection.build(attributes = {}, ...)</tt> - returns one or more new objects of the collection type that have been instantiated
# otherwise sets their foreign keys to +NULL+.
# * <tt>collection.empty?</tt> - Returns +true+ if there are no associated objects.
# * <tt>collection.size</tt> - Returns the number of associated objects.
# * <tt>collection.find</tt> - Finds an associated object according to the same rules as Base.find.
# * <tt>collection.build(attributes = {}, ...)</tt> - Returns one or more new objects of the collection type that have been instantiated
# with +attributes+ and linked to this object through a foreign key, but have not yet been saved. *Note:* This only works if an
# associated object already exists, not if it's +nil+!
# * <tt>collection.create(attributes = {})</tt> - returns a new object of the collection type that has been instantiated
# * <tt>collection.create(attributes = {})</tt> - Returns a new object of the collection type that has been instantiated
# with +attributes+, linked to this object through a foreign key, and that has already been saved (if it passed the validation).
# *Note:* This only works if an associated object already exists, not if it's +nil+!
#
# Example: A +Firm+ class declares <tt>has_many :clients</tt>, which will add:
# Example: A Firm class declares <tt>has_many :clients</tt>, which will add:
# * <tt>Firm#clients</tt> (similar to <tt>Clients.find :all, :conditions => "firm_id = #{id}"</tt>)
# * <tt>Firm#clients<<</tt>
# * <tt>Firm#clients.delete</tt>
@ -640,45 +640,45 @@ module ActiveRecord
# The declaration can also include an options hash to specialize the behavior of the association.
#
# Options are:
# * <tt>:class_name</tt> - specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So <tt>has_many :products</tt> will by default be linked to the +Product+ class, but
# if the real class name is +SpecialProduct+, you'll have to specify it with this option.
# * <tt>:conditions</tt> - specify the conditions that the associated objects must meet in order to be included as a +WHERE+
# * <tt>:class_name</tt> - Specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So <tt>has_many :products</tt> will by default be linked to the Product class, but
# if the real class name is SpecialProduct, you'll have to specify it with this option.
# * <tt>:conditions</tt> - Specify the conditions that the associated objects must meet in order to be included as a +WHERE+
# SQL fragment, such as <tt>price > 5 AND name LIKE 'B%'</tt>. Record creations from the association are scoped if a hash
# is used. <tt>has_many :posts, :conditions => {:published => true}</tt> will create published posts with <tt>@blog.posts.create</tt>
# or <tt>@blog.posts.build</tt>.
# * <tt>:order</tt> - specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
# such as <tt>last_name, first_name DESC</tt>
# * <tt>:foreign_key</tt> - specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and +_id+ suffixed. So a +Person+ class that makes a +has_many+ association will use +person_id+
# as the default +foreign_key+.
# * <tt>:dependent</tt> - if set to <tt>:destroy</tt> all the associated objects are destroyed
# alongside this object by calling their destroy method. If set to <tt>:delete_all</tt> all associated
# objects are deleted *without* calling their destroy method. If set to <tt>:nullify</tt> all associated
# objects' foreign keys are set to +NULL+ *without* calling their save callbacks. *Warning:* This option is ignored when also using
# the <tt>through</tt> option.
# * <tt>:finder_sql</tt> - specify a complete SQL statement to fetch the association. This is a good way to go for complex
# * <tt>:order</tt> - Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
# such as <tt>last_name, first_name DESC</tt>.
# * <tt>:foreign_key</tt> - Specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+ association will use "person_id"
# as the default <tt>:foreign_key</tt>.
# * <tt>:dependent</tt> - If set to <tt>:destroy</tt> all the associated objects are destroyed
# alongside this object by calling their +destroy+ method. If set to <tt>:delete_all</tt> all associated
# objects are deleted *without* calling their +destroy+ method. If set to <tt>:nullify</tt> all associated
# objects' foreign keys are set to +NULL+ *without* calling their +save+ callbacks. *Warning:* This option is ignored when also using
# the <tt>:through</tt> option.
# * <tt>:finder_sql</tt> - Specify a complete SQL statement to fetch the association. This is a good way to go for complex
# associations that depend on multiple tables. Note: When this option is used, +find_in_collection+ is _not_ added.
# * <tt>:counter_sql</tt> - specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is
# * <tt>:counter_sql</tt> - Specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is
# specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
# * <tt>:extend</tt> - specify a named module for extending the proxy. See "Association extensions".
# * <tt>:include</tt> - specify second-order associations that should be eager loaded when the collection is loaded.
# * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
# * <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 the first 4 rows.
# * <tt>:select</tt>: By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if you, for example, want to do a join
# * <tt>:extend</tt> - Specify a named module for extending the proxy. See "Association extensions".
# * <tt>:include</tt> - Specify second-order associations that should be eager loaded when the collection is loaded.
# * <tt>:group</tt> - An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
# * <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 the first 4 rows.
# * <tt>:select</tt> - By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if you, for example, want to do a join
# but not include the joined columns.
# * <tt>:as</tt>: Specifies a polymorphic interface (See <tt>#belongs_to</tt>).
# * <tt>:through</tt>: Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt>
# * <tt>:as</tt> - Specifies a polymorphic interface (See <tt>belongs_to</tt>).
# * <tt>:through</tt> - Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt>
# are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a <tt>belongs_to</tt>
# or <tt>has_many</tt> association on the join model.
# * <tt>:source</tt>: Specifies the source association name used by <tt>has_many :through</tt> queries. Only use it if the name cannot be
# * <tt>:source</tt> - Specifies the source association name used by <tt>has_many :through</tt> queries. Only use it if the name cannot be
# inferred from the association. <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either <tt>:subscribers</tt> or
# <tt>:subscriber</tt> on +Subscription+, unless a <tt>:source</tt> is given.
# * <tt>:source_type</tt>: Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
# <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
# * <tt>:source_type</tt> - Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
# association is a polymorphic +belongs_to+.
# * <tt>:uniq</tt> - if set to +true+, duplicates will be omitted from the collection. Useful in conjunction with <tt>:through</tt>.
# * <tt>:readonly</tt> - if set to +true+, all the associated objects are readonly through the association.
# * <tt>:uniq</tt> - If true, duplicates will be omitted from the collection. Useful in conjunction with <tt>:through</tt>.
# * <tt>:readonly</tt> - If true, all the associated objects are readonly through the association.
#
# Option examples:
# has_many :comments, :order => "posted_on"
@ -712,14 +712,14 @@ module ActiveRecord
# Adds the following methods for retrieval and query of a single associated object:
# +association+ is replaced with the symbol passed as the first argument, so
# <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
# * <tt>association(force_reload = false)</tt> - returns the associated object. +nil+ is returned if none is found.
# * <tt>association=(associate)</tt> - assigns the associate object, extracts the primary key, sets it as the foreign key,
# * <tt>association(force_reload = false)</tt> - Returns the associated object. +nil+ is returned if none is found.
# * <tt>association=(associate)</tt> - Assigns the associate object, extracts the primary key, sets it as the foreign key,
# and saves the associate object.
# * <tt>association.nil?</tt> - returns +true+ if there is no associated object.
# * <tt>build_association(attributes = {})</tt> - returns a new object of the associated type that has been instantiated
# * <tt>association.nil?</tt> - Returns +true+ if there is no associated object.
# * <tt>build_association(attributes = {})</tt> - Returns a new object of the associated type that has been instantiated
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved. Note: This ONLY works if
# an association already exists. It will NOT work if the association is +nil+.
# * <tt>create_association(attributes = {})</tt> - returns a new object of the associated type that has been instantiated
# * <tt>create_association(attributes = {})</tt> - Returns a new object of the associated type that has been instantiated
# with +attributes+, linked to this object through a foreign key, and that has already been saved (if it passed the validation).
#
# Example: An Account class declares <tt>has_one :beneficiary</tt>, which will add:
@ -732,28 +732,28 @@ module ActiveRecord
# The declaration can also include an options hash to specialize the behavior of the association.
#
# Options are:
# * <tt>:class_name</tt> - specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So <tt>has_one :manager</tt> will by default be linked to the +Manager+ class, but
# if the real class name is +Person+, you'll have to specify it with this option.
# * <tt>:conditions</tt> - specify the conditions that the associated object must meet in order to be included as a +WHERE+
# * <tt>:class_name</tt> - Specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but
# if the real class name is Person, you'll have to specify it with this option.
# * <tt>:conditions</tt> - Specify the conditions that the associated object must meet in order to be included as a +WHERE+
# SQL fragment, such as <tt>rank = 5</tt>.
# * <tt>:order</tt> - specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
# such as <tt>last_name, first_name DESC</tt>
# * <tt>:dependent</tt> - if set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
# * <tt>:order</tt> - Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
# such as <tt>last_name, first_name DESC</tt>.
# * <tt>:dependent</tt> - If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to <tt>:nullify</tt>, the associated
# object's foreign key is set to +NULL+. Also, association is assigned.
# * <tt>:foreign_key</tt> - specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and +_id+ suffixed. So a +Person+ class that makes a +has_one+ association will use +person_id+
# as the default +foreign_key+.
# * <tt>:include</tt> - specify second-order associations that should be eager loaded when this object is loaded.
# * <tt>:as</tt>: Specifies a polymorphic interface (See <tt>#belongs_to</tt>).
# * <tt>:foreign_key</tt> - Specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association will use "person_id"
# as the default <tt>:foreign_key</tt>.
# * <tt>:include</tt> - Specify second-order associations that should be eager loaded when this object is loaded.
# * <tt>:as</tt> - Specifies a polymorphic interface (See <tt>belongs_to</tt>).
# * <tt>:through</tt>: Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt>
# are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a
# <tt>has_one</tt> or <tt>belongs_to</tt> association on the join model.
# * <tt>:source</tt>: Specifies the source association name used by <tt>has_one :through</tt> queries. Only use it if the name cannot be
# * <tt>:source</tt> - Specifies the source association name used by <tt>has_one :through</tt> queries. Only use it if the name cannot be
# inferred from the association. <tt>has_one :favorite, :through => :favorites</tt> will look for a
# <tt>:favorite</tt> on +Favorite+, unless a <tt>:source</tt> is given.
# * <tt>:readonly</tt> - if set to +true+, the associated object is readonly through the association.
# <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
# * <tt>:readonly</tt> - If true, the associated object is readonly through the association.
#
# Option examples:
# has_one :credit_card, :dependent => :destroy # destroys the associated credit card
@ -796,12 +796,12 @@ module ActiveRecord
# Adds the following methods for retrieval and query for a single associated object for which this object holds an id:
# +association+ is replaced with the symbol passed as the first argument, so
# <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
# * <tt>association(force_reload = false)</tt> - returns the associated object. +nil+ is returned if none is found.
# * <tt>association=(associate)</tt> - assigns the associate object, extracts the primary key, and sets it as the foreign key.
# * <tt>association.nil?</tt> - returns +true+ if there is no associated object.
# * <tt>build_association(attributes = {})</tt> - returns a new object of the associated type that has been instantiated
# * <tt>association(force_reload = false)</tt> - Returns the associated object. +nil+ is returned if none is found.
# * <tt>association=(associate)</tt> - Assigns the associate object, extracts the primary key, and sets it as the foreign key.
# * <tt>association.nil?</tt> - Returns +true+ if there is no associated object.
# * <tt>build_association(attributes = {})</tt> - Returns a new object of the associated type that has been instantiated
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
# * <tt>create_association(attributes = {})</tt> - returns a new object of the associated type that has been instantiated
# * <tt>create_association(attributes = {})</tt> - Returns a new object of the associated type that has been instantiated
# with +attributes+, linked to this object through a foreign key, and that has already been saved (if it passed the validation).
#
# Example: A Post class declares <tt>belongs_to :author</tt>, which will add:
@ -814,34 +814,35 @@ module ActiveRecord
# The declaration can also include an options hash to specialize the behavior of the association.
#
# Options are:
# * <tt>:class_name</tt> - specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So <tt>has_one :author</tt> will by default be linked to the +Author+ class, but
# if the real class name is +Person+, you'll have to specify it with this option.
# * <tt>:conditions</tt> - specify the conditions that the associated object must meet in order to be included as a +WHERE+
# * <tt>:class_name</tt> - Specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So <tt>has_one :author</tt> will by default be linked to the Author class, but
# if the real class name is Person, you'll have to specify it with this option.
# * <tt>:conditions</tt> - Specify the conditions that the associated object must meet in order to be included as a +WHERE+
# SQL fragment, such as <tt>authorized = 1</tt>.
# * <tt>:order</tt> - specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
# such as <tt>last_name, first_name DESC</tt>
# * <tt>:foreign_key</tt> - specify the foreign key used for the association. By default this is guessed to be the name
# of the association with an +_id+ suffix. So a class that defines a +belongs_to :person+ association will use +person_id+ as the default +foreign_key+.
# Similarly, +belongs_to :favorite_person, :class_name => "Person"+ will use a foreign key of +favorite_person_id+.
# * <tt>:dependent</tt> - if set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
# * <tt>:order</tt> - Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
# such as <tt>last_name, first_name DESC</tt>.
# * <tt>:foreign_key</tt> - Specify the foreign key used for the association. By default this is guessed to be the name
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt> association will use
# "person_id" as the default <tt>:foreign_key</tt>. Similarly, <tt>belongs_to :favorite_person, :class_name => "Person"</tt>
# will use a foreign key of "favorite_person_id".
# * <tt>:dependent</tt> - If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. This option should not be specified when
# <tt>belongs_to</tt> is used in conjunction with a <tt>has_many</tt> relationship on another class because of the potential to leave
# orphaned records behind.
# * <tt>:counter_cache</tt> - caches the number of belonging objects on the associate class through the use of +increment_counter+
# * <tt>:counter_cache</tt> - Caches the number of belonging objects on the associate class through the use of +increment_counter+
# and +decrement_counter+. The counter cache is incremented when an object of this class is created and decremented when it's
# destroyed. This requires that a column named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging +Comment+ class)
# is used on the associate class (such as a +Post+ class). You can also specify a custom counter cache column by providing
# destroyed. This requires that a column named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
# is used on the associate class (such as a Post class). You can also specify a custom counter cache column by providing
# a column name instead of a +true+/+false+ value to this option (e.g., <tt>:counter_cache => :my_custom_counter</tt>.)
# When creating a counter cache column, the database statement or migration must specify a default value of <tt>0</tt>, failing to do
# this results in a counter with NULL value, which will never increment.
# Note: Specifying a counter_cache will add it to that model's list of readonly attributes using #attr_readonly.
# * <tt>:include</tt> - specify second-order associations that should be eager loaded when this object is loaded.
# this results in a counter with +NULL+ value, which will never increment.
# Note: Specifying a counter cache will add it to that model's list of readonly attributes using +attr_readonly+.
# * <tt>:include</tt> - Specify second-order associations that should be eager loaded when this object is loaded.
# Not allowed if the association is polymorphic.
# * <tt>:polymorphic</tt> - specify this association is a polymorphic association by passing +true+.
# * <tt>:polymorphic</tt> - Specify this association is a polymorphic association by passing +true+.
# Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
# to the attr_readonly list in the associated classes (e.g. class Post; attr_readonly :comments_count; end).
# * <tt>:readonly</tt> - if set to +true+, the associated object is readonly through the association.
# to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
# * <tt>:readonly</tt> - If true, the associated object is readonly through the association.
#
# Option examples:
# belongs_to :firm, :foreign_key => "client_of"
@ -926,14 +927,14 @@ module ActiveRecord
end
# Associates two classes via an intermediate join table. Unless the join table is explicitly specified as
# an option, it is guessed using the lexical order of the class names. So a join between +Developer+ and +Project+
# will give the default join table name of +developers_projects+ because "D" outranks "P". Note that this precedence
# is calculated using the <tt><</tt> operator for <tt>String</tt>. This means that if the strings are of different lengths,
# an option, it is guessed using the lexical order of the class names. So a join between Developer and Project
# will give the default join table name of "developers_projects" because "D" outranks "P". Note that this precedence
# is calculated using the <tt><</tt> operator for String. This means that if the strings are of different lengths,
# and the strings are equal when compared up to the shortest length, then the longer string is considered of higher
# lexical precedence than the shorter one. For example, one would expect the tables <tt>paper_boxes</tt> and <tt>papers</tt>
# to generate a join table name of <tt>papers_paper_boxes</tt> because of the length of the name <tt>paper_boxes</tt>,
# but it in fact generates a join table name of <tt>paper_boxes_papers</tt>. Be aware of this caveat, and use the
# custom <tt>join_table</tt> option if you need to.
# lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers"
# to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes",
# but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the
# custom <tt>:join_table</tt> option if you need to.
#
# Deprecated: Any additional fields added to the join table will be placed as attributes when pulling records out through
# +has_and_belongs_to_many+ associations. Records returned from join tables with additional attributes will be marked as
@ -943,23 +944,23 @@ module ActiveRecord
# Adds the following methods for retrieval and query:
# +collection+ is replaced with the symbol passed as the first argument, so
# <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
# * <tt>collection(force_reload = false)</tt> - returns an array of all the associated objects.
# * <tt>collection(force_reload = false)</tt> - Returns an array of all the associated objects.
# An empty array is returned if none are found.
# * <tt>collection<<(object, ...)</tt> - adds one or more objects to the collection by creating associations in the join table
# * <tt>collection<<(object, ...)</tt> - Adds one or more objects to the collection by creating associations in the join table
# (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
# * <tt>collection.delete(object, ...)</tt> - removes one or more objects from the collection by removing their associations from the join table.
# * <tt>collection.delete(object, ...)</tt> - Removes one or more objects from the collection by removing their associations from the join table.
# This does not destroy the objects.
# * <tt>collection=objects</tt> - replaces the collection's content by deleting and adding objects as appropriate.
# * <tt>collection_singular_ids</tt> - returns an array of the associated objects' ids
# * <tt>collection_singular_ids=ids</tt> - replace the collection by the objects identified by the primary keys in +ids+
# * <tt>collection.clear</tt> - removes every object from the collection. This does not destroy the objects.
# * <tt>collection.empty?</tt> - returns +true+ if there are no associated objects.
# * <tt>collection.size</tt> - returns the number of associated objects.
# * <tt>collection.find(id)</tt> - finds an associated object responding to the +id+ and that
# * <tt>collection=objects</tt> - Replaces the collection's content by deleting and adding objects as appropriate.
# * <tt>collection_singular_ids</tt> - Returns an array of the associated objects' ids.
# * <tt>collection_singular_ids=ids</tt> - Replace the collection by the objects identified by the primary keys in +ids+.
# * <tt>collection.clear</tt> - Removes every object from the collection. This does not destroy the objects.
# * <tt>collection.empty?</tt> - Returns +true+ if there are no associated objects.
# * <tt>collection.size</tt> - Returns the number of associated objects.
# * <tt>collection.find(id)</tt> - Finds an associated object responding to the +id+ and that
# meets the condition that it has to be associated with this object.
# * <tt>collection.build(attributes = {})</tt> - returns a new object of the collection type that has been instantiated
# * <tt>collection.build(attributes = {})</tt> - Returns a new object of the collection type that has been instantiated
# with +attributes+ and linked to this object through the join table, but has not yet been saved.
# * <tt>collection.create(attributes = {})</tt> - returns a new object of the collection type that has been instantiated
# * <tt>collection.create(attributes = {})</tt> - Returns a new object of the collection type that has been instantiated
# with +attributes+, linked to this object through the join table, and that has already been saved (if it passed the validation).
#
# Example: A Developer class declares <tt>has_and_belongs_to_many :projects</tt>, which will add:
@ -978,38 +979,38 @@ module ActiveRecord
# The declaration may include an options hash to specialize the behavior of the association.
#
# Options are:
# * <tt>:class_name</tt> - specify the class name of the association. Use it only if that name can't be inferred
# * <tt>:class_name</tt> - Specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So <tt>has_and_belongs_to_many :projects</tt> will by default be linked to the
# +Project+ class, but if the real class name is +SuperProject+, you'll have to specify it with this option.
# * <tt>:join_table</tt> - specify the name of the join table if the default based on lexical order isn't what you want.
# Project class, but if the real class name is SuperProject, you'll have to specify it with this option.
# * <tt>:join_table</tt> - Specify the name of the join table if the default based on lexical order isn't what you want.
# WARNING: If you're overwriting the table name of either class, the +table_name+ method MUST be declared underneath any
# +has_and_belongs_to_many+ declaration in order to work.
# * <tt>:foreign_key</tt> - specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and +_id+ suffixed. So a +Person+ class that makes a +has_and_belongs_to_many+ association
# will use +person_id+ as the default +foreign_key+.
# * <tt>:association_foreign_key</tt> - specify the association foreign key used for the association. By default this is
# guessed to be the name of the associated class in lower-case and +_id+ suffixed. So if the associated class is +Project+,
# the +has_and_belongs_to_many+ association will use +project_id+ as the default association +foreign_key+.
# * <tt>:conditions</tt> - specify the conditions that the associated object must meet in order to be included as a +WHERE+
# * <tt>:foreign_key</tt> - Specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_and_belongs_to_many+ association
# will use "person_id" as the default <tt>:foreign_key</tt>.
# * <tt>:association_foreign_key</tt> - Specify the association foreign key used for the association. By default this is
# guessed to be the name of the associated class in lower-case and "_id" suffixed. So if the associated class is Project,
# the +has_and_belongs_to_many+ association will use "project_id" as the default <tt>:association_foreign_key</tt>.
# * <tt>:conditions</tt> - Specify the conditions that the associated object must meet in order to be included as a +WHERE+
# SQL fragment, such as <tt>authorized = 1</tt>. Record creations from the association are scoped if a hash is used.
# <tt>has_many :posts, :conditions => {:published => true}</tt> will create published posts with <tt>@blog.posts.create</tt>
# or <tt>@blog.posts.build</tt>.
# * <tt>:order</tt> - specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
# * <tt>:order</tt> - Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
# such as <tt>last_name, first_name DESC</tt>
# * <tt>:uniq</tt> - if set to +true+, duplicate associated objects will be ignored by accessors and query methods
# * <tt>:finder_sql</tt> - overwrite the default generated SQL statement used to fetch the association with a manual statement
# * <tt>:delete_sql</tt> - overwrite the default generated SQL statement used to remove links between the associated
# classes with a manual statement
# * <tt>:insert_sql</tt> - overwrite the default generated SQL statement used to add links between the associated classes
# with a manual statement
# * <tt>:extend</tt> - anonymous module for extending the proxy, see "Association extensions".
# * <tt>:include</tt> - specify second-order associations that should be eager loaded when the collection is loaded.
# * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
# * <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 the first 4 rows.
# * <tt>:select</tt>: By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join
# * <tt>:uniq</tt> - If true, duplicate associated objects will be ignored by accessors and query methods.
# * <tt>:finder_sql</tt> - Overwrite the default generated SQL statement used to fetch the association with a manual statement
# * <tt>:delete_sql</tt> - Overwrite the default generated SQL statement used to remove links between the associated
# classes with a manual statement.
# * <tt>:insert_sql</tt> - Overwrite the default generated SQL statement used to add links between the associated classes
# with a manual statement.
# * <tt>:extend</tt> - Anonymous module for extending the proxy, see "Association extensions".
# * <tt>:include</tt> - Specify second-order associations that should be eager loaded when the collection is loaded.
# * <tt>:group</tt> - An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
# * <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 the first 4 rows.
# * <tt>:select</tt> - By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join
# but not include the joined columns.
# * <tt>:readonly</tt> - if set to +true+, all the associated objects are readonly through the association.
# * <tt>:readonly</tt> - If true, all the associated objects are readonly through the association.
#
# Option examples:
# has_and_belongs_to_many :projects

View File

@ -92,13 +92,15 @@ module ActiveRecord #:nodoc:
class DangerousAttributeError < ActiveRecordError
end
# Raised when you've tried to access a column which wasn't
# loaded by your finder. Typically this is because <tt>:select</tt>
# has been specified.
# Raised when you've tried to access a column which wasn't loaded by your finder.
# Typically this is because <tt>:select</tt> has been specified.
class MissingAttributeError < NoMethodError
end
class AttributeAssignmentError < ActiveRecordError #:nodoc:
# Raised when an error occured while doing a mass assignment to an attribute through the
# <tt>attributes=</tt> method. The exception has an +attribute+ property that is the name of the
# offending attribute.
class AttributeAssignmentError < ActiveRecordError
attr_reader :exception, :attribute
def initialize(message, exception, attribute)
@exception = exception
@ -107,7 +109,10 @@ module ActiveRecord #:nodoc:
end
end
class MultiparameterAssignmentErrors < ActiveRecordError #:nodoc:
# Raised when there are multiple errors while doing a mass assignment through the +attributes+
# method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
# objects, each corresponding to the error while assigning to an attribute.
class MultiparameterAssignmentErrors < ActiveRecordError
attr_reader :errors
def initialize(errors)
@errors = errors
@ -230,8 +235,8 @@ module ActiveRecord #:nodoc:
# == Accessing attributes before they have been typecasted
#
# Sometimes you want to be able to read the raw attribute data without having the column-determined typecast run its course first.
# That can be done by using the <attribute>_before_type_cast accessors that all attributes have. For example, if your Account model
# has a balance attribute, you can call account.balance_before_type_cast or account.id_before_type_cast.
# That can be done by using the <tt><attribute>_before_type_cast</tt> accessors that all attributes have. For example, if your Account model
# has a balance attribute, you can call <tt>account.balance_before_type_cast</tt> or <tt>account.id_before_type_cast</tt>.
#
# This is especially useful in validation situations where the user might supply a string for an integer field and you want to display
# the original string back in an error message. Accessing the attribute normally would typecast the string to 0, which isn't what you
@ -332,26 +337,26 @@ module ActiveRecord #:nodoc:
#
# == Exceptions
#
# * +ActiveRecordError+ -- generic error class and superclass of all other errors raised by Active Record
# * +AdapterNotSpecified+ -- the configuration hash used in <tt>establish_connection</tt> didn't include an
# * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
# * AdapterNotSpecified - The configuration hash used in <tt>establish_connection</tt> didn't include an
# <tt>:adapter</tt> key.
# * +AdapterNotFound+ -- the <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a non-existent adapter
# * AdapterNotFound - The <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a non-existent adapter
# (or a bad spelling of an existing one).
# * +AssociationTypeMismatch+ -- the object assigned to the association wasn't of the type specified in the association definition.
# * +SerializationTypeMismatch+ -- the serialized object wasn't of the class specified as the second parameter.
# * +ConnectionNotEstablished+ -- no connection has been established. Use <tt>establish_connection</tt> before querying.
# * +RecordNotFound+ -- no record responded to the find* method.
# Either the row with the given ID doesn't exist or the row didn't meet the additional restrictions.
# * +StatementInvalid+ -- the database server rejected the SQL statement. The precise error is added in the message.
# Either the record with the given ID doesn't exist or the record didn't meet the additional restrictions.
# * +MultiparameterAssignmentErrors+ -- collection of errors that occurred during a mass assignment using the
# +attributes=+ method. The +errors+ property of this exception contains an array of +AttributeAssignmentError+
# * AssociationTypeMismatch - The object assigned to the association wasn't of the type specified in the association definition.
# * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.
# * ConnectionNotEstablished+ - No connection has been established. Use <tt>establish_connection</tt> before querying.
# * RecordNotFound - No record responded to the +find+ method. Either the row with the given ID doesn't exist
# or the row didn't meet the additional restrictions. Some +find+ calls do not raise this exception to signal
# nothing was found, please check its documentation for further details.
# * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
# * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the
# <tt>attributes=</tt> method. The +errors+ property of this exception contains an array of AttributeAssignmentError
# objects that should be inspected to determine which attributes triggered the errors.
# * +AttributeAssignmentError+ -- an error occurred while doing a mass assignment through the +attributes=+ method.
# * AttributeAssignmentError - An error occurred while doing a mass assignment through the <tt>attributes=</tt> method.
# You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error.
#
# *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level).
# So it's possible to assign a logger to the class through Base.logger= which will then be used by all
# So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
# instances in the current object space.
class Base
# Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then passed
@ -601,7 +606,7 @@ module ActiveRecord #:nodoc:
# User.create(:first_name => 'Jamie')
#
# # Create an Array of new objects
# User.create([{:first_name => 'Jamie'}, {:first_name => 'Jeremy'}])
# User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
#
# # Create a single object and pass it into a block to set other attributes.
# User.create(:first_name => 'Jamie') do |u|
@ -609,7 +614,7 @@ module ActiveRecord #:nodoc:
# 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|
# User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
# u.is_admin = false
# end
def create(attributes = nil, &block)
@ -626,18 +631,18 @@ module ActiveRecord #:nodoc:
# Updates an object (or multiple objects) and saves it to the database, if validations pass.
# The resulting object is returned whether the object was saved successfully to the database or not.
#
# ==== Options
# ==== Attributes
#
# +id+ This should be the id or an array of ids to be updated
# +attributes+ This should be a Hash of attributes to be set on the object, or an array of Hashes.
# * +id+ - This should be the id or an array of ids to be updated.
# * +attributes+ - This should be a Hash of attributes to be set on the object, or an array of Hashes.
#
# ==== Examples
#
# # Updating one record:
# Person.update(15, {:user_name => 'Samuel', :group => 'expert'})
# Person.update(15, { :user_name => 'Samuel', :group => 'expert' })
#
# # Updating multiple records:
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy"} }
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
# Person.update(people.keys, people.values)
def update(id, attributes)
if id.is_a?(Array)
@ -656,9 +661,9 @@ module ActiveRecord #:nodoc:
#
# Objects are _not_ instantiated with this method.
#
# ==== Options
# ==== Attributes
#
# +id+ Can be either an Integer or an Array of Integers
# * +id+ - Can be either an Integer or an Array of Integers.
#
# ==== Examples
#
@ -679,9 +684,9 @@ module ActiveRecord #:nodoc:
# This essentially finds the object (or multiple objects) with the given id, creates a new object
# from the attributes, and then calls destroy on it.
#
# ==== Options
# ==== Attributes
#
# +id+ Can be either an Integer or an Array of Integers
# * +id+ - Can be either an Integer or an Array of Integers.
#
# ==== Examples
#
@ -702,12 +707,12 @@ module ActiveRecord #:nodoc:
# Updates all records with details given if they match a set of conditions supplied, limits and order can
# also be supplied.
#
# ==== Options
# ==== Attributes
#
# +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 <tt>:limit</tt> and/or <tt>:order</tt>, see the examples for usage.
# * +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 <tt>:limit</tt> and/or <tt>:order</tt>, see the examples for usage.
#
# ==== Examples
#
@ -734,9 +739,9 @@ module ActiveRecord #:nodoc:
# many records. If you want to simply delete records without worrying about dependent associations or
# callbacks, use the much faster +delete_all+ method instead.
#
# ==== Options
# ==== Attributes
#
# +conditions+ Conditions are specified the same way as with +find+ method.
# * +conditions+ - Conditions are specified the same way as with +find+ method.
#
# ==== Example
#
@ -752,9 +757,9 @@ module ActiveRecord #:nodoc:
# calling the destroy method and invoking callbacks. This is a single SQL query, much more efficient
# than destroy_all.
#
# ==== Options
# ==== Attributes
#
# +conditions+ Conditions are specified the same way as with +find+ method.
# * +conditions+ - Conditions are specified the same way as with +find+ method.
#
# ==== Example
#
@ -772,9 +777,9 @@ module ActiveRecord #:nodoc:
# The use of this method should be restricted to complicated SQL queries that can't be executed
# using the ActiveRecord::Calculations class methods. Look into those before using this.
#
# ==== Options
# ==== Attributes
#
# +sql+: An SQL statement which should return a count query from the database, see the example below
# * +sql+ - An SQL statement which should return a count query from the database, see the example below.
#
# ==== Examples
#
@ -790,12 +795,11 @@ module ActiveRecord #:nodoc:
# with the given ID, altering the given hash of counters by the amount
# given by the corresponding value:
#
# ==== Options
# ==== Attributes
#
# +id+ The id of the object you wish to update a counter on
# +counters+ An Array of Hashes containing the names of the fields
# to update as keys and the amount to update the field by as
# values
# * +id+ - The id of the object you wish to update a counter on.
# * +counters+ - An Array of Hashes containing the names of the fields
# to update as keys and the amount to update the field by as values.
#
# ==== Examples
#
@ -821,10 +825,10 @@ module ActiveRecord #:nodoc:
# For example, a DiscussionBoard may cache post_count and comment_count otherwise every time the board is
# shown it would have to run an SQL query to find how many posts and comments there are.
#
# ==== Options
# ==== Attributes
#
# +counter_name+ The name of the field that should be incremented
# +id+ The id of the object that should be incremented
# * +counter_name+ - The name of the field that should be incremented.
# * +id+ - The id of the object that should be incremented.
#
# ==== Examples
#
@ -838,10 +842,10 @@ module ActiveRecord #:nodoc:
#
# This works the same as increment_counter but reduces the column value by 1 instead of increasing it.
#
# ==== Options
# ==== Attributes
#
# +counter_name+ The name of the field that should be decremented
# +id+ The id of the object that should be decremented
# * +counter_name+ - The name of the field that should be decremented.
# * +id+ - The id of the object that should be decremented.
#
# ==== Examples
#
@ -886,9 +890,9 @@ module ActiveRecord #:nodoc:
# overwritten by URL/form hackers. If you'd rather start from an all-open default and restrict
# attributes as needed, have a look at attr_protected.
#
# ==== Options
# ==== Attributes
#
# <tt>*attributes</tt> A comma separated list of symbols that represent columns _not_ to be protected
# * <tt>*attributes</tt> A comma separated list of symbols that represent columns _not_ to be protected
#
# ==== Examples
#
@ -927,10 +931,10 @@ module ActiveRecord #:nodoc:
# The serialization is done through YAML. If +class_name+ is specified, the serialized object must be of that
# class on retrieval or +SerializationTypeMismatch+ will be raised.
#
# ==== Options
# ==== Attributes
#
# +attr_name+ The field name that should be serialized
# +class_name+ Optional, class name that the object type should be equal to
# * +attr_name+ - The field name that should be serialized.
# * +class_name+ - Optional, class name that the object type should be equal to.
#
# ==== Example
# # Serialize a preferences attribute
@ -1757,7 +1761,7 @@ module ActiveRecord #:nodoc:
# class Article < ActiveRecord::Base
# def self.find_with_scope
# with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }, :create => { :blog_id => 1 }) do
# with_scope(:find => { :limit => 10})
# with_scope(:find => { :limit => 10 })
# find(:all) # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
# end
# with_scope(:find => { :conditions => "author_id = 3" })
@ -2238,40 +2242,53 @@ module ActiveRecord #:nodoc:
save!
end
# Initializes the +attribute+ to zero if nil and adds the value passed as +by+ (default is one). Only makes sense for number-based attributes. Returns self.
# Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1).
# The increment is performed directly on the underlying attribute, no setter is invoked.
# Only makes sense for number-based attributes. Returns +self+.
def increment(attribute, by = 1)
self[attribute] ||= 0
self[attribute] += by
self
end
# Increments the +attribute+ and saves the record.
# Note: Updates made with this method aren't subjected to validation checks
# Wrapper around +increment+ that saves the record. This method differs from
# its non-bang version in that it passes through the attribute setter.
# Saving is not subjected to validation checks. Returns +true+ if the
# record could be saved.
def increment!(attribute, by = 1)
increment(attribute, by).update_attribute(attribute, self[attribute])
end
# Initializes the +attribute+ to zero if nil and subtracts the value passed as +by+ (default is one). Only makes sense for number-based attributes. Returns self.
# Initializes +attribute+ to zero if +nil+ and subtracts the value passed as +by+ (default is 1).
# The decrement is performed directly on the underlying attribute, no setter is invoked.
# Only makes sense for number-based attributes. Returns +self+.
def decrement(attribute, by = 1)
self[attribute] ||= 0
self[attribute] -= by
self
end
# Decrements the +attribute+ and saves the record.
# Note: Updates made with this method aren't subjected to validation checks
# Wrapper around +decrement+ that saves the record. This method differs from
# its non-bang version in that it passes through the attribute setter.
# Saving is not subjected to validation checks. Returns +true+ if the
# record could be saved.
def decrement!(attribute, by = 1)
decrement(attribute, by).update_attribute(attribute, self[attribute])
end
# Turns an +attribute+ that's currently true into false and vice versa. Returns self.
# Assigns to +attribute+ the boolean opposite of <tt>attribute?</tt>. So
# if the predicate returns +true+ the attribute will become +false+. This
# method toggles directly the underlying value without calling any setter.
# Returns +self+.
def toggle(attribute)
self[attribute] = !send("#{attribute}?")
self
end
# Toggles the +attribute+ and saves the record.
# Note: Updates made with this method aren't subjected to validation checks
# Wrapper around +toggle+ that saves the record. This method differs from
# its non-bang version in that it passes through the attribute setter.
# Saving is not subjected to validation checks. Returns +true+ if the
# record could be saved.
def toggle!(attribute)
toggle(attribute).update_attribute(attribute, self[attribute])
end

View File

@ -44,6 +44,12 @@ module ActiveRecord
@query_cache_enabled = old
end
# Clears the query cache.
#
# One reason you may wish to call this method explicitly is between queries
# that ask the database to randomize results. Otherwise the cache would see
# the same SQL query and repeatedly return the same result each time, silently
# undermining the randomness you were expecting.
def clear_query_cache
@query_cache.clear if @query_cache
end

View File

@ -73,7 +73,7 @@ module ActiveRecord
# REFERENTIAL INTEGRITY ====================================
# Override to turn off referential integrity while executing +&block+
# Override to turn off referential integrity while executing <tt>&block</tt>.
def disable_referential_integrity(&block)
yield
end
@ -101,7 +101,7 @@ module ActiveRecord
false
end
# Lazily verify this connection, calling +active?+ only if it hasn't
# Lazily verify this connection, calling <tt>active?</tt> only if it hasn't
# been called for +timeout+ seconds.
def verify!(timeout)
now = Time.now.to_i

View File

@ -146,19 +146,19 @@ module ActiveRecord
#
# Options:
#
# * <tt>:host</tt> -- Defaults to localhost
# * <tt>:port</tt> -- Defaults to 3306
# * <tt>:socket</tt> -- Defaults to /tmp/mysql.sock
# * <tt>:username</tt> -- Defaults to root
# * <tt>:password</tt> -- Defaults to nothing
# * <tt>:database</tt> -- The name of the database. No default, must be provided.
# * <tt>:encoding</tt> -- (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection
# * <tt>:sslkey</tt> -- Necessary to use MySQL with an SSL connection
# * <tt>:sslcert</tt> -- Necessary to use MySQL with an SSL connection
# * <tt>:sslcapath</tt> -- Necessary to use MySQL with an SSL connection
# * <tt>:sslcipher</tt> -- Necessary to use MySQL with an SSL connection
# * <tt>:host</tt> - Defaults to "localhost".
# * <tt>:port</tt> - Defaults to 3306.
# * <tt>:socket</tt> - Defaults to "/tmp/mysql.sock".
# * <tt>:username</tt> - Defaults to "root"
# * <tt>:password</tt> - Defaults to nothing.
# * <tt>:database</tt> - The name of the database. No default, must be provided.
# * <tt>:encoding</tt> - (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection.
# * <tt>:sslkey</tt> - Necessary to use MySQL with an SSL connection.
# * <tt>:sslcert</tt> - Necessary to use MySQL with an SSL connection.
# * <tt>:sslcapath</tt> - Necessary to use MySQL with an SSL connection.
# * <tt>:sslcipher</tt> - Necessary to use MySQL with an SSL connection.
#
# By default, the MysqlAdapter will consider all columns of type tinyint(1)
# By default, the MysqlAdapter will consider all columns of type <tt>tinyint(1)</tt>
# as boolean. If you wish to disable this emulation (which was the default
# behavior in versions 0.13.1 and earlier) you can add the following line
# to your environment.rb file:

View File

@ -228,15 +228,15 @@ module ActiveRecord
#
# Options:
#
# * <tt>:host</tt> -- Defaults to localhost
# * <tt>:port</tt> -- Defaults to 5432
# * <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 <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.
# * <tt>:host</tt> - Defaults to "localhost".
# * <tt>:port</tt> - Defaults to 5432.
# * <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 <tt>:schema_order</tt> option.
# * <tt>:encoding</tt> - An optional client encoding that is used in a <tt>SET client_encoding TO <encoding></tt> call on the connection.
# * <tt>:min_messages</tt> - An optional client min messages that is used in a <tt>SET client_min_messages TO <min_messages></tt> 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.
class PostgreSQLAdapter < AbstractAdapter
# Returns 'PostgreSQL' as adapter name for identification purposes.
def adapter_name

View File

@ -70,7 +70,7 @@ module ActiveRecord
#
# Options:
#
# * <tt>:database</tt> -- Path to the database file.
# * <tt>:database</tt> - Path to the database file.
class SQLiteAdapter < AbstractAdapter
def adapter_name #:nodoc:
'SQLite'

View File

@ -426,7 +426,7 @@ end
# == Support for YAML defaults
#
# You probably already know how to use YAML to set and reuse defaults in
# your +database.yml+ file,. You can use the same technique in your fixtures:
# your <tt>database.yml</tt> file. You can use the same technique in your fixtures:
#
# DEFAULTS: &DEFAULTS
# created_on: <%= 3.weeks.ago.to_s(:db) %>

View File

@ -153,6 +153,17 @@ module ActiveRecord
end
end
# Returns the AssociationReflection object specified in the <tt>:through</tt> option
# of a HasManyThrough or HasOneThrough association. Example:
#
# class Post < ActiveRecord::Base
# has_many :taggings
# has_many :tags, :through => :taggings
# end
#
# tags_reflection = Post.reflect_on_association(:tags)
# taggings_reflection = tags_reflection.through_reflection
#
def through_reflection
@through_reflection ||= options[:through] ? active_record.reflect_on_association(options[:through]) : false
end
@ -168,7 +179,8 @@ module ActiveRecord
# 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
# class Post < ActiveRecord::Base
# has_many :taggings
# has_many :tags, :through => :taggings
# end
#

View File

@ -678,7 +678,7 @@ module ActiveRecord
# * <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>: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.
@ -784,7 +784,7 @@ module ActiveRecord
#
# Configuration options:
# * <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>: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.
@ -802,8 +802,8 @@ module ActiveRecord
end
# Validates whether the value of the specified attribute is numeric by trying to convert it to
# a float with Kernel.Float (if <tt>integer</tt> is false) or applying it to the regular expression
# <tt>/\A[\+\-]?\d+\Z/</tt> (if <tt>integer</tt> is set to true).
# a float with Kernel.Float (if <tt>only_integer</tt> is false) or applying it to the regular expression
# <tt>/\A[\+\-]?\d+\Z/</tt> (if <tt>only_integer</tt> is set to true).
#
# class Person < ActiveRecord::Base
# validates_numericality_of :value, :on => :create

View File

@ -14,12 +14,19 @@ module ActiveResource
# Person maps to the resources people, very similarly to Active Record) and a +site+ value, which holds the
# URI of the resources.
#
# class Person < ActiveResource::Base
# self.site = "http://api.people.com:3000/"
# end
# class Person < ActiveResource::Base
# self.site = "http://api.people.com:3000/"
# end
#
# Now the Person class is mapped to RESTful resources located at <tt>http://api.people.com:3000/people/</tt>, and
# you can now use Active Resource's lifecycles methods to manipulate resources.
# you can now use Active Resource's lifecycles methods to manipulate resources. In the case where you already have
# an existing model with the same name as the desired RESTful resource you can set the +element_name+ value.
#
# class PersonResource < ActiveResource::Base
# self.site = "http://api.people.com:3000/"
# self.element_name = "person"
# end
#
#
# == Lifecycle methods
#
@ -72,13 +79,13 @@ module ActiveResource
#
# You can validate resources client side by overriding validation methods in the base class.
#
# class Person < ActiveResource::Base
# self.site = "http://api.people.com:3000/"
# protected
# def validate
# errors.add("last", "has invalid characters") unless last =~ /[a-zA-Z]*/
# end
# end
# class Person < ActiveResource::Base
# self.site = "http://api.people.com:3000/"
# protected
# def validate
# errors.add("last", "has invalid characters") unless last =~ /[a-zA-Z]*/
# end
# end
#
# See the ActiveResource::Validations documentation for more information.
#
@ -118,18 +125,17 @@ module ActiveResource
# exception.
#
# # GET http://api.people.com:3000/people/999.xml
# ryan = Person.find(999) # => Raises ActiveResource::ResourceNotFound
# # => Response = 404
# ryan = Person.find(999) # 404, raises ActiveResource::ResourceNotFound
#
# <tt>404</tt> is just one of the HTTP error response codes that ActiveResource will handle with its own exception. The
# following HTTP response codes will also result in these exceptions:
#
# 200 - 399:: Valid response, no exception
# 404:: ActiveResource::ResourceNotFound
# 409:: ActiveResource::ResourceConflict
# 422:: ActiveResource::ResourceInvalid (rescued by save as validation errors)
# 401 - 499:: ActiveResource::ClientError
# 500 - 599:: ActiveResource::ServerError
# * 200..399 - Valid response, no exception
# * 404 - ActiveResource::ResourceNotFound
# * 409 - ActiveResource::ResourceConflict
# * 422 - ActiveResource::ResourceInvalid (rescued by save as validation errors)
# * 401..499 - ActiveResource::ClientError
# * 500..599 - ActiveResource::ServerError
#
# These custom exceptions allow you to deal with resource errors more naturally and with more precision
# rather than returning a general HTTP error. For example:
@ -177,12 +183,15 @@ module ActiveResource
# self.timeout = 5
# end
#
# This sets the +timeout+ to 5 seconds. You can adjust the timeout to a value suitable for the RESTful API
# This sets the +timeout+ to 5 seconds. You can adjust the +timeout+ to a value suitable for the RESTful API
# you are accessing. It is recommended to set this to a reasonably low value to allow your Active Resource
# clients (especially if you are using Active Resource in a Rails application) to fail-fast (see
# http://en.wikipedia.org/wiki/Fail-fast) rather than cause cascading failures that could incapacitate your
# server.
#
# When a timeout occurs, an ActiveResource::TimeoutError is raised. You should rescue from
# ActiveResource::TimeoutError in your Active Resource method calls.
#
# Internally, Active Resource relies on Ruby's Net::HTTP library to make HTTP requests. Setting +timeout+
# sets the <tt>read_timeout</tt> of the internal Net::HTTP instance to the same value. The default
# <tt>read_timeout</tt> is 60 seconds on most Ruby implementations.
@ -229,7 +238,7 @@ module ActiveResource
end
end
# Gets the user for REST HTTP authentication
# Gets the user for REST HTTP authentication.
def user
# Not using superclass_delegating_reader. See +site+ for explanation
if defined?(@user)
@ -239,13 +248,13 @@ module ActiveResource
end
end
# Sets the user for REST HTTP authentication
# Sets the user for REST HTTP authentication.
def user=(user)
@connection = nil
@user = user
end
# Gets the password for REST HTTP authentication
# Gets the password for REST HTTP authentication.
def password
# Not using superclass_delegating_reader. See +site+ for explanation
if defined?(@password)
@ -255,13 +264,13 @@ module ActiveResource
end
end
# Sets the password for REST HTTP authentication
# Sets the password for REST HTTP authentication.
def password=(password)
@connection = nil
@password = password
end
# Sets the format that attributes are sent and received in from a mime type reference. Example:
# Sets the format that attributes are sent and received in from a mime type reference:
#
# Person.format = :json
# Person.find(1) # => GET /people/1.json
@ -269,7 +278,7 @@ module ActiveResource
# Person.format = ActiveResource::Formats::XmlFormat
# Person.find(1) # => GET /people/1.xml
#
# Default format is :xml.
# Default format is <tt>:xml</tt>.
def format=(mime_type_reference_or_format)
format = mime_type_reference_or_format.is_a?(Symbol) ?
ActiveResource::Formats[mime_type_reference_or_format] : mime_type_reference_or_format
@ -278,7 +287,7 @@ module ActiveResource
connection.format = format if site
end
# Returns the current format, default is ActiveResource::Formats::XmlFormat
# Returns the current format, default is ActiveResource::Formats::XmlFormat.
def format # :nodoc:
read_inheritable_attribute("format") || ActiveResource::Formats[:xml]
end
@ -367,9 +376,9 @@ module ActiveResource
# will split from the prefix options.
#
# ==== Options
# +prefix_options+:: A hash to add a prefix to the request for nested URL's (e.g., <tt>:account_id => 19</tt>
# +prefix_options+ - A hash to add a prefix to the request for nested URLs (e.g., <tt>:account_id => 19</tt>
# would yield a URL like <tt>/accounts/19/purchases.xml</tt>).
# +query_options+:: A hash to add items to the query string for the request.
# +query_options+ - A hash to add items to the query string for the request.
#
# ==== Examples
# Post.element_path(1)
@ -393,9 +402,9 @@ module ActiveResource
# will split from the +prefix_options+.
#
# ==== Options
# +prefix_options+:: A hash to add a prefix to the request for nested URL's (e.g., <tt>:account_id => 19</tt>
# would yield a URL like <tt>/accounts/19/purchases.xml</tt>).
# +query_options+:: A hash to add items to the query string for the request.
# * +prefix_options+ - A hash to add a prefix to the request for nested URL's (e.g., <tt>:account_id => 19</tt>
# would yield a URL like <tt>/accounts/19/purchases.xml</tt>).
# * +query_options+ - A hash to add items to the query string for the request.
#
# ==== Examples
# Post.collection_path
@ -431,40 +440,34 @@ module ActiveResource
# ==== Examples
# Person.create(:name => 'Jeremy', :email => 'myname@nospam.com', :enabled => true)
# my_person = Person.find(:first)
# my_person.email
# # => myname@nospam.com
# my_person.email # => myname@nospam.com
#
# dhh = Person.create(:name => 'David', :email => 'dhh@nospam.com', :enabled => true)
# dhh.valid?
# # => true
# dhh.new?
# # => false
# dhh.valid? # => true
# dhh.new? # => false
#
# # We'll assume that there's a validation that requires the name attribute
# that_guy = Person.create(:name => '', :email => 'thatguy@nospam.com', :enabled => true)
# that_guy.valid?
# # => false
# that_guy.new?
# # => true
#
# that_guy.valid? # => false
# that_guy.new? # => true
def create(attributes = {})
returning(self.new(attributes)) { |res| res.save }
end
# Core method for finding resources. Used similarly to Active Record's find method.
# Core method for finding resources. Used similarly to Active Record's +find+ method.
#
# ==== Arguments
# The first argument is considered to be the scope of the query. That is, how many
# resources are returned from the request. It can be one of the following.
#
# * <tt>:one</tt>: Returns a single resource.
# * <tt>:first</tt>: Returns the first resource found.
# * <tt>:all</tt>: Returns every resource that matches the request.
# * <tt>:one</tt> - Returns a single resource.
# * <tt>:first</tt> - Returns the first resource found.
# * <tt>:all</tt> - Returns every resource that matches the request.
#
# ==== Options
#
# * +from+: Sets the path or custom method that resources will be fetched from.
# * +params+: Sets query and prefix (nested URL) parameters.
# * <tt>:from</tt> - Sets the path or custom method that resources will be fetched from.
# * <tt>:params</tt> - Sets query and prefix (nested URL) parameters.
#
# ==== Examples
# Person.find(1)
@ -511,19 +514,14 @@ module ActiveResource
# All options specify prefix and query parameters.
#
# ==== Examples
# Event.delete(2)
# # => DELETE /events/2
# Event.delete(2) # sends DELETE /events/2
#
# Event.create(:name => 'Free Concert', :location => 'Community Center')
# my_event = Event.find(:first)
# # => Events (id: 7)
# Event.delete(my_event.id)
# # => DELETE /events/7
# my_event = Event.find(:first) # let's assume this is event with ID 7
# Event.delete(my_event.id) # sends DELETE /events/7
#
# # Let's assume a request to events/5/cancel.xml
# Event.delete(params[:id])
# # => DELETE /events/5
#
# Event.delete(params[:id]) # sends DELETE /events/5
def delete(id, options = {})
connection.delete(element_path(id, options))
end
@ -532,11 +530,9 @@ module ActiveResource
#
# ==== Examples
# Note.create(:title => 'Hello, world.', :body => 'Nothing more for now...')
# Note.exists?(1)
# # => true
# Note.exists?(1) # => true
#
# Note.exists(1349)
# # => false
# Note.exists(1349) # => false
def exists?(id, options = {})
if id
prefix_options, query_options = split_options(options[:params])
@ -626,7 +622,7 @@ module ActiveResource
attr_accessor :attributes #:nodoc:
attr_accessor :prefix_options #:nodoc:
# Constructor method for new resources; the optional +attributes+ parameter takes a +Hash+
# Constructor method for new resources; the optional +attributes+ parameter takes a hash
# of attributes for the new resource.
#
# ==== Examples
@ -643,27 +639,26 @@ module ActiveResource
load(attributes)
end
# Returns a clone of the resource that hasn't been assigned an id yet and
# Returns a clone of the resource that hasn't been assigned an +id+ yet and
# is treated as a new resource.
#
# ryan = Person.find(1)
# not_ryan = ryan.clone
# not_ryan.new? # => true
# ryan = Person.find(1)
# not_ryan = ryan.clone
# not_ryan.new? # => true
#
# Any active resource member attributes will NOT be cloned, though all other
# attributes are. This is to prevent the conflict between any prefix_options
# attributes are. This is to prevent the conflict between any +prefix_options+
# that refer to the original parent resource and the newly cloned parent
# resource that does not exist.
#
# ryan = Person.find(1)
# ryan.address = StreetAddress.find(1, :person_id => ryan.id)
# ryan.hash = {:not => "an ARes instance"}
#
# not_ryan = ryan.clone
# not_ryan.new? # => true
# not_ryan.address # => NoMethodError
# not_ryan.hash # => {:not => "an ARes instance"}
#
# ryan = Person.find(1)
# ryan.address = StreetAddress.find(1, :person_id => ryan.id)
# ryan.hash = {:not => "an ARes instance"}
#
# not_ryan = ryan.clone
# not_ryan.new? # => true
# not_ryan.address # => NoMethodError
# not_ryan.hash # => {:not => "an ARes instance"}
def clone
# Clone all attributes except the pk and any nested ARes
cloned = attributes.reject {|k,v| k == self.class.primary_key || v.is_a?(ActiveResource::Base)}.inject({}) do |attrs, (k, v)|
@ -684,16 +679,13 @@ module ActiveResource
#
# ==== Examples
# not_new = Computer.create(:brand => 'Apple', :make => 'MacBook', :vendor => 'MacMall')
# not_new.new?
# # => false
# not_new.new? # => false
#
# is_new = Computer.new(:brand => 'IBM', :make => 'Thinkpad', :vendor => 'IBM')
# is_new.new?
# # => true
# is_new.new? # => true
#
# is_new.save
# is_new.new?
# # => false
# is_new.new? # => false
#
def new?
id.nil?
@ -715,7 +707,7 @@ module ActiveResource
end
# Test for equality. Resource are equal if and only if +other+ is the same object or
# is an instance of the same class, is not +new?+, and has the same +id+.
# is an instance of the same class, is not <tt>new?</tt>, and has the same +id+.
#
# ==== Examples
# ryan = Person.create(:name => 'Ryan')
@ -756,17 +748,13 @@ module ActiveResource
# ==== Examples
# my_invoice = Invoice.create(:customer => 'That Company')
# next_invoice = my_invoice.dup
# next_invoice.new?
# # => true
# next_invoice.new? # => true
#
# next_invoice.save
# next_invoice == my_invoice
# # => false (different id attributes)
# next_invoice == my_invoice # => false (different id attributes)
#
# my_invoice.customer
# # => That Company
# next_invoice.customer
# # => That Company
# my_invoice.customer # => That Company
# next_invoice.customer # => That Company
def dup
returning self.class.new do |resource|
resource.attributes = @attributes
@ -781,16 +769,12 @@ module ActiveResource
#
# ==== Examples
# my_company = Company.new(:name => 'RoleModel Software', :owner => 'Ken Auer', :size => 2)
# my_company.new?
# # => true
# my_company.save
# # => POST /companies/ (create)
# my_company.new? # => true
# my_company.save # sends POST /companies/ (create)
#
# my_company.new?
# # => false
# my_company.new? # => false
# my_company.size = 10
# my_company.save
# # => PUT /companies/1 (update)
# my_company.save # sends PUT /companies/1 (update)
def save
new? ? create : update
end
@ -801,20 +785,17 @@ module ActiveResource
# my_id = 3
# my_person = Person.find(my_id)
# my_person.destroy
# Person.find(my_id)
# # => 404 (Resource Not Found)
# Person.find(my_id) # 404 (Resource Not Found)
#
# new_person = Person.create(:name => 'James')
# new_id = new_person.id
# # => 7
# new_id = new_person.id # => 7
# new_person.destroy
# Person.find(new_id)
# # => 404 (Resource Not Found)
# Person.find(new_id) # 404 (Resource Not Found)
def destroy
connection.delete(element_path, self.class.headers)
end
# Evaluates to <tt>true</tt> if this resource is not +new?+ and is
# Evaluates to <tt>true</tt> if this resource is not <tt>new?</tt> and is
# found on the remote service. Using this method, you can check for
# resources that may have been deleted between the object's instantiation
# and actions on it.
@ -822,17 +803,14 @@ module ActiveResource
# ==== Examples
# Person.create(:name => 'Theodore Roosevelt')
# that_guy = Person.find(:first)
# that_guy.exists?
# # => true
# that_guy.exists? # => true
#
# that_lady = Person.new(:name => 'Paul Bean')
# that_lady.exists?
# # => false
# that_lady.exists? # => false
#
# guys_id = that_guy.id
# Person.delete(guys_id)
# that_guy.exists?
# # => false
# that_guy.exists? # => false
def exists?
!new? && self.class.exists?(to_param, :params => prefix_options)
end
@ -844,11 +822,11 @@ module ActiveResource
# attribute, so it has the same options as the +to_xml+ methods in
# ActiveSupport.
#
# indent:: Set the indent level for the XML output (default is +2+).
# dasherize:: Boolean option to determine whether or not element names should
# replace underscores with dashes (default is <tt>false</tt>).
# skip_instruct:: Toggle skipping the +instruct!+ call on the XML builder
# that generates the XML declaration (default is <tt>false</tt>).
# * <tt>:indent</tt> - Set the indent level for the XML output (default is +2+).
# * <tt>:dasherize</tt> - Boolean option to determine whether or not element names should
# replace underscores with dashes (default is <tt>false</tt>).
# * <tt>:skip_instruct</tt> - Toggle skipping the +instruct!+ call on the XML builder
# that generates the XML declaration (default is <tt>false</tt>).
#
# ==== Examples
# my_group = SubsidiaryGroup.find(:first)
@ -870,30 +848,26 @@ module ActiveResource
#
# ==== Examples
# my_branch = Branch.find(:first)
# my_branch.name
# # => Wislon Raod
# my_branch.name # => "Wislon Raod"
#
# # Another client fixes the typo...
#
# my_branch.name
# # => Wislon Raod
# my_branch.name # => "Wislon Raod"
# my_branch.reload
# my_branch.name
# # => Wilson Road
# my_branch.name # => "Wilson Road"
def reload
self.load(self.class.find(to_param, :params => @prefix_options).attributes)
end
# A method to manually load attributes from a hash. Recursively loads collections of
# resources. This method is called in initialize and create when a +Hash+ of attributes
# resources. This method is called in +initialize+ and +create+ when a hash of attributes
# is provided.
#
# ==== Examples
# my_attrs = {:name => 'J&J Textiles', :industry => 'Cloth and textiles'}
#
# the_supplier = Supplier.find(:first)
# the_supplier.name
# # => 'J&M Textiles'
# the_supplier.name # => 'J&M Textiles'
# the_supplier.load(my_attrs)
# the_supplier.name('J&J Textiles')
#
@ -924,10 +898,10 @@ module ActiveResource
self
end
# For checking respond_to? without searching the attributes (which is faster).
# For checking <tt>respond_to?</tt> without searching the attributes (which is faster).
alias_method :respond_to_without_attributes?, :respond_to?
# A method to determine if an object responds to a message (e.g., a method call). In Active Resource, a +Person+ object with a
# A method to determine if an object responds to a message (e.g., a method call). In Active Resource, a Person object with a
# +name+ attribute can answer <tt>true</tt> to <tt>my_person.respond_to?("name")</tt>, <tt>my_person.respond_to?("name=")</tt>, and
# <tt>my_person.respond_to?("name?")</tt>.
def respond_to?(method, include_priv = false)

View File

@ -23,10 +23,7 @@ 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:
# Assigns a new value to the hash:
#
# hash = HashWithIndifferentAccess.new
# hash[:key] = "value"
@ -35,25 +32,15 @@ class HashWithIndifferentAccess < Hash
regular_writer(convert_key(key), convert_value(value))
end
# Updates the instantized hash with values from the second:
#
# Updates the instantized hash with values from the second.
# hash_1 = HashWithIndifferentAccess.new
# hash_1[:key] = "value"
#
# Example:
# hash_2 = HashWithIndifferentAccess.new
# hash_2[:key] = "New Value!"
#
# >> 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!"}
# 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)) }
@ -62,7 +49,13 @@ class HashWithIndifferentAccess < Hash
alias_method :merge!, :update
# Checks the hash for a key matching the argument passed in
# Checks the hash for a key matching the argument passed in:
#
# hash = HashWithIndifferentAccess.new
# hash["key"] = "value"
# hash.key? :key # => true
# hash.key? "key" # => true
#
def key?(key)
super(convert_key(key))
end
@ -76,7 +69,13 @@ class HashWithIndifferentAccess < Hash
super(convert_key(key), *extras)
end
# Returns an array of the values at the specified indicies.
# Returns an array of the values at the specified indices:
#
# hash = HashWithIndifferentAccess.new
# hash[:a] = "x"
# hash[:b] = "y"
# hash.values_at("a", "b") # => ["x", "y"]
#
def values_at(*indices)
indices.collect {|key| self[convert_key(key)]}
end

View File

@ -3,6 +3,11 @@ require 'singleton'
# The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
# and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
# in inflections.rb.
#
# The Rails core team has stated patches for the inflections library will not be accepted
# in order to avoid breaking legacy applications which may be relying on errant inflections.
# If you discover an incorrect inflection and require it for your application, you'll need
# to correct it yourself (explained below).
module Inflector
# A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
# inflection rules. Examples:

View File

@ -7,4 +7,9 @@ class ApplicationController < ActionController::Base
# See ActionController::RequestForgeryProtection for details
# Uncomment the :secret if you're not using the cookie session store
protect_from_forgery # :secret => '<%= app_secret %>'
# See ActionController::Base for details
# Uncomment this to filter the contents of submitted sensitive data parameters
# from your application log (in this case, all fields with names like "password").
# filter_parameter_logging :password
end

View File

@ -572,11 +572,13 @@ module Rails
attr_accessor :plugin_loader
# Enables or disables plugin reloading. You can get around this setting per plugin.
# If <tt>reload_plugins?</tt> is false, add this to your plugin's init.rb to make it reloadable:
# If <tt>reload_plugins?</tt> is false, add this to your plugin's <tt>init.rb</tt>
# to make it reloadable:
#
# Dependencies.load_once_paths.delete lib_path
#
# If <tt>reload_plugins?</tt> is true, add this to your plugin's init.rb to only load it once:
# If <tt>reload_plugins?</tt> is true, add this to your plugin's <tt>init.rb</tt>
# to only load it once:
#
# Dependencies.load_once_paths << lib_path
#
@ -676,7 +678,7 @@ module Rails
YAML::load(ERB.new(IO.read(database_configuration_file)).result)
end
# The path to the current environment's file (development.rb, etc.). By
# The path to the current environment's file (<tt>development.rb</tt>, etc.). By
# default the file is at <tt>config/environments/#{environment}.rb</tt>.
def environment_path
"#{root_path}/config/environments/#{environment}.rb"

View File

@ -1,14 +1,14 @@
module Rails
# The Plugin class should be an object which provides the following methods:
#
# * +name+ - used during initialisation to order the plugin (based on name and
# the contents of <tt>config.plugins</tt>)
# * +valid?+ - returns true if this plugin can be loaded
# * +load_paths+ - each path within the returned array will be added to the $LOAD_PATH
# * +load+ - finally 'load' the plugin.
# * +name+ - Used during initialisation to order the plugin (based on name and
# the contents of <tt>config.plugins</tt>).
# * +valid?+ - Returns true if this plugin can be loaded.
# * +load_paths+ - Each path within the returned array will be added to the <tt>$LOAD_PATH</tt>.
# * +load+ - Finally 'load' the plugin.
#
# These methods are expected by the Rails::Plugin::Locator and Rails::Plugin::Loader classes.
# The default implementation returns the <tt>lib</tt> directory as its </tt>load_paths</tt>,
# The default implementation returns the <tt>lib</tt> directory as its <tt>load_paths</tt>,
# and evaluates <tt>init.rb</tt> when <tt>load</tt> is called.
#
# You can also inspect the about.yml data programmatically:
@ -31,13 +31,13 @@ module Rails
File.directory?(directory) && (has_lib_directory? || has_init_file?)
end
# Returns a list of paths this plugin wishes to make available in $LOAD_PATH
# Returns a list of paths this plugin wishes to make available in <tt>$LOAD_PATH</tt>.
def load_paths
report_nonexistant_or_empty_plugin! unless valid?
has_lib_directory? ? [lib_path] : []
end
# Evaluates a plugin's init.rb file
# Evaluates a plugin's init.rb file.
def load(initializer)
return if loaded?
report_nonexistant_or_empty_plugin! unless valid?