diff --git a/actionmailer/README b/actionmailer/README
index 67e8266e92d..0e16ea6ec6b 100755
--- a/actionmailer/README
+++ b/actionmailer/README
@@ -19,8 +19,7 @@ are all set up this way. An example of such a method:
recipients recipient
subject "[Signed up] Welcome #{recipient}"
from "system@loudthinking.com"
-
- body(:recipient => recipient)
+ body :recipient => recipient
end
The body of the email is created by using an Action View template (regular
@@ -78,21 +77,26 @@ Example:
end
end
-This Mailman can be the target for Postfix. In Rails, you would use the runner like this:
+This Mailman can be the target for Postfix or other MTAs. In Rails, you would use the runner in the
+trivial case like this:
./script/runner 'Mailman.receive(STDIN.read)'
+However, invoking Rails in the runner for each mail to be received is very resource intensive. A single
+instance of Rails should be run within a daemon if it is going to be utilized to process more than just
+a limited number of email.
+
== Configuration
The Base class has the full list of configuration options. Here's an example:
-ActionMailer::Base.smtp_settings = {
- :address=>'smtp.yourserver.com', # default: localhost
- :port=>'25', # default: 25
- :user_name=>'user',
- :password=>'pass',
- :authentication=>:plain # :plain, :login or :cram_md5
-}
+ ActionMailer::Base.smtp_settings = {
+ :address => 'smtp.yourserver.com', # default: localhost
+ :port => '25', # default: 25
+ :user_name => 'user',
+ :password => 'pass',
+ :authentication => :plain # :plain, :login or :cram_md5
+ }
== Dependencies
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index aafa26e79eb..7ed133d0992 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -35,7 +35,7 @@ module ActionMailer #:nodoc:
# * subject - The subject of your email. Sets the Subject: header.
# * from - Who the email you are sending is from. Sets the From: header.
# * cc - Takes one or more email addresses. These addresses will receive a carbon copy of your email. Sets the Cc: header.
- # * bcc - Takes one or more email address. These addresses will receive a blind carbon copy of your email. Sets the Bcc header.
+ # * bcc - Takes one or more email address. These addresses will receive a blind carbon copy of your email. Sets the Bcc: header.
# * sent_on - The date on which the message was sent. If not set, the header wil be set by the delivery agent.
# * content_type - Specify the content type of the message. Defaults to text/plain.
# * headers - Specify additional headers to be set for the message, e.g. headers 'X-Mail-Count' => 107370.
@@ -127,11 +127,11 @@ module ActionMailer #:nodoc:
#
# class MyMailer < ActionMailer::Base
# def signup_notification(recipient)
- # recipients recipient.email_address_with_name
- # subject "New account information"
- # body "account" => recipient
- # from "system@example.com"
- # content_type "text/html" # Here's where the magic happens
+ # recipients recipient.email_address_with_name
+ # subject "New account information"
+ # from "system@example.com"
+ # body :account => recipient
+ # content_type "text/html"
# end
# end
#
@@ -145,6 +145,7 @@ module ActionMailer #:nodoc:
# recipients recipient.email_address_with_name
# subject "New account information"
# from "system@example.com"
+ # content_type "multipart/alternative"
#
# part :content_type => "text/html",
# :body => render_message("signup-as-html", :account => recipient)
@@ -167,9 +168,14 @@ module ActionMailer #:nodoc:
# * signup_notification.text.x-yaml.erb
#
# Each would be rendered and added as a separate part to the message,
- # with the corresponding content type. The same body hash is passed to
- # each template.
+ # with the corresponding content type. The content type for the entire
+ # message is automatically set to multipart/alternative, which indicates
+ # that the email contains multiple different representations of the same email
+ # body. The same body hash is passed to each template.
#
+ # Implicit template rendering is not performed if any attachments or parts have been added to the email.
+ # This means that you'll have to manually add each part to the email and set the content type of the email
+ # to multipart/alternative.
#
# = Attachments
#
@@ -209,12 +215,12 @@ module ActionMailer #:nodoc:
# * :domain - If you need to specify a HELO domain, you can do it here.
# * :user_name - If your mail server requires authentication, set the username in this setting.
# * :password - If your mail server requires authentication, set the password in this setting.
- # * :authentication - If your mail server requires authentication, you need to specify the authentication type here.
- # This is a symbol and one of :plain, :login, :cram_md5
+ # * :authentication - If your mail server requires authentication, you need to specify the authentication type here.
+ # This is a symbol and one of :plain, :login, :cram_md5.
#
- # * sendmail_settings - Allows you to override options for the :sendmail delivery method
- # * :location - The location of the sendmail executable, defaults to "/usr/sbin/sendmail"
- # * :arguments - The command line arguments
+ # * sendmail_settings - Allows you to override options for the :sendmail delivery method.
+ # * :location - The location of the sendmail executable. Defaults to /usr/sbin/sendmail.
+ # * :arguments - The command line arguments. Defaults to -i -t.
#
# * raise_delivery_errors - Whether or not errors should be raised if the email fails to be delivered.
#
@@ -226,17 +232,17 @@ module ActionMailer #:nodoc:
# * deliveries - Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful
# for unit and functional testing.
#
- # * default_charset - The default charset used for the body and to encode the subject. Defaults to UTF-8. You can also
- # pick a different charset from inside a method with @charset.
+ # * default_charset - The default charset used for the body and to encode the subject. Defaults to UTF-8. You can also
+ # pick a different charset from inside a method with +charset+.
# * default_content_type - The default content type used for the main part of the message. Defaults to "text/plain". You
- # can also pick a different content type from inside a method with @content_type.
- # * default_mime_version - The default mime version used for the message. Defaults to "1.0". You
- # can also pick a different value from inside a method with @mime_version.
+ # can also pick a different content type from inside a method with +content_type+.
+ # * default_mime_version - The default mime version used for the message. Defaults to 1.0. You
+ # can also pick a different value from inside a method with +mime_version+.
# * default_implicit_parts_order - When a message is built implicitly (i.e. multiple parts are assembled from templates
# which specify the content type in their filenames) this variable controls how the parts are ordered. Defaults to
- # ["text/html", "text/enriched", "text/plain"]. Items that appear first in the array have higher priority in the mail client
+ # ["text/html", "text/enriched", "text/plain"]. Items that appear first in the array have higher priority in the mail client
# and appear last in the mime encoded message. You can also pick a different order from inside a method with
- # @implicit_parts_order.
+ # +implicit_parts_order+.
class Base
include AdvAttrAccessor, PartContainer
include ActionController::UrlWriter if Object.const_defined?(:ActionController)
diff --git a/actionpack/lib/action_controller/mime_responds.rb b/actionpack/lib/action_controller/mime_responds.rb
index a17782cafc2..1dbd8b9e6f3 100644
--- a/actionpack/lib/action_controller/mime_responds.rb
+++ b/actionpack/lib/action_controller/mime_responds.rb
@@ -92,7 +92,7 @@ module ActionController #:nodoc:
# with the remaining data.
#
# Note that you can define your own XML parameter parser which would allow you to describe multiple entities
- # in a single request (i.e., by wrapping them all in a single root note), but if you just go with the flow
+ # in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow
# and accept Rails' defaults, life will be much easier.
#
# If you need to use a MIME type which isn't supported by default, you can register your own handlers in
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index b8600fe4457..6d97038da92 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -73,30 +73,54 @@ module ActionView
# There are also methods for helping to build form tags in link:classes/ActionView/Helpers/FormOptionsHelper.html,
# link:classes/ActionView/Helpers/DateHelper.html, and link:classes/ActionView/Helpers/ActiveRecordHelper.html
module FormHelper
- # Creates a form and a scope around a specific model object that is used as a base for questioning about
- # values for the fields.
+ # Creates a form and a scope around a specific model object that is used as
+ # a base for questioning about values for the fields.
+ #
+ # Rails provides succint resource-oriented form generation with +form_for+
+ # like this:
+ #
+ # <% form_for @offer do |f| %>
+ # <%= f.label :version, 'Version' %>:
+ # <%= f.text_field :version %>
+ # <%= f.label :author, 'Author' %>:
+ # <%= f.text_field :author %>
+ # <% end %>
+ #
+ # There, +form_for+ is able to generate the rest of RESTful parameters
+ # based on introspection on the record, but to understand what it does we
+ # need to dig first into the alternative generic usage it is based upon.
+ #
+ # === Generic form_for
+ #
+ # The generic way to call +form_for+ requires a few arguments:
#
# <% form_for :person, @person, :url => { :action => "update" } do |f| %>
# <%= f.error_messages %>
- # First name: <%= f.text_field :first_name %>
- # Last name : <%= f.text_field :last_name %>
- # Biography : <%= f.text_area :biography %>
- # Admin? : <%= f.check_box :admin %>
+ # First name: <%= f.text_field :first_name %>
+ # Last name : <%= f.text_field :last_name %>
+ # Biography : <%= f.text_area :biography %>
+ # Admin? : <%= f.check_box :admin %>
# <% end %>
#
- # Worth noting is that the form_for tag is called in a ERb evaluation block, not an ERb output block. So that's <% %>,
- # not <%= %>. Also worth noting is that form_for yields a form_builder object, in this example as f, which emulates
- # the API for the stand-alone FormHelper methods, but without the object name. So instead of text_field :person, :name,
- # you get away with f.text_field :name. Notice that you can even do <%= f.error_messages %> to display the
- # error messsages of the model object in question.
+ # Worth noting is that the +form_for+ tag is called in a ERb evaluation block,
+ # not an ERb output block. So that's <% %>, not <%= %>. Also
+ # worth noting is that +form_for+ yields a form builder object, in this
+ # example as +f+, which emulates the API for the stand-alone FormHelper
+ # methods, but without the object name. So instead of text_field :person, :name,
+ # you get away with f.text_field :name. Notice that you can even do
+ # <%= f.error_messages %> to display the error messsages of the model
+ # object in question.
#
- # Even further, the form_for method allows you to more easily escape the instance variable convention. So while the stand-alone
- # approach would require text_field :person, :name, :object => person
- # to work with local variables instead of instance ones, the form_for calls remain the same. You simply declare once with
- # :person, person and all subsequent field calls save :person and :object => person.
+ # Even further, the +form_for+ method allows you to more easily escape the
+ # instance variable convention. So while the stand-alone approach would require
+ # text_field :person, :name, :object => person to work with local
+ # variables instead of instance ones, the +form_for+ calls remain the same.
+ # You simply declare once with :person, person and all subsequent
+ # field calls save :person and :object => person.
#
- # Also note that form_for doesn't create an exclusive scope. It's still possible to use both the stand-alone FormHelper methods
- # and methods from FormTagHelper. For example:
+ # Also note that +form_for+ doesn't create an exclusive scope. It's still
+ # possible to use both the stand-alone FormHelper methods and methods from
+ # FormTagHelper. For example:
#
# <% form_for :person, @person, :url => { :action => "update" } do |f| %>
# First name: <%= f.text_field :first_name %>
@@ -105,22 +129,26 @@ module ActionView
# Admin? : <%= check_box_tag "person[admin]", @person.company.admin? %>
# <% end %>
#
- # Note: This also works for the methods in FormOptionHelper and DateHelper that are designed to work with an object as base,
- # like FormOptionHelper#collection_select and DateHelper#datetime_select.
+ # This also works for the methods in FormOptionHelper and DateHelper that are
+ # designed to work with an object as base, like FormOptionHelper#collection_select
+ # and DateHelper#datetime_select.
#
- # HTML attributes for the form tag can be given as :html => {...}. For example:
+ # HTML attributes for the form tag can be given as :html => {...}.
+ # For example:
#
# <% form_for :person, @person, :html => {:id => 'person_form'} do |f| %>
# ...
# <% end %>
#
- # The above form will then have the id attribute with the value person_form, which you can then
- # style with CSS or manipulate with JavaScript.
+ # The above form will then have the +id+ attribute with the value "person_form",
+ # which you can then style with CSS or manipulate with JavaScript.
#
# === Relying on record identification
#
- # In addition to manually configuring the form_for call, you can also rely on record identification, which will use
- # the conventions and named routes of that approach. Examples:
+ # As we said above, in addition to manually configuring the +form_for+ call,
+ # you can rely on record identification, which will use the conventions and
+ # named routes of that approach. This is the preferred way to use +form_for+
+ # nowadays:
#
# <% form_for(@post) do |f| %>
# ...
@@ -140,7 +168,7 @@ module ActionView
#
# This will expand to be the same as:
#
- # <% form_for :post, @post, :url => posts_path, :html => { :class => "new_post", :id => "new_post" } do |f| %>
+ # <% form_for :post, Post.new, :url => posts_path, :html => { :class => "new_post", :id => "new_post" } do |f| %>
# ...
# <% end %>
#
@@ -150,7 +178,7 @@ module ActionView
# ...
# <% end %>
#
- # And for namespaced routes, like admin_post_url:
+ # And for namespaced routes, like +admin_post_url+:
#
# <% form_for([:admin, @post]) do |f| %>
# ...
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index 375ebfcdc58..38c8d18cb08 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -120,17 +120,72 @@ module ActionView
# exception.
#
# ==== Examples
+ # Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
+ # and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
+ # your application on resources and use
+ #
+ # link_to "Profile", profile_path(@profile)
+ # # => Profile
+ #
+ # or the even pithier
+ #
+ # link_to "Profile", @profile
+ # # => Profile
+ #
+ # in place of the older more verbose, non-resource-oriented
+ #
+ # link_to "Profile", :controller => "profiles", :action => "show", :id => @profile
+ # # => Profile
+ #
+ # Similarly,
+ #
+ # link_to "Profiles", profiles_path
+ # # => Profiles
+ #
+ # is better than
+ #
+ # link_to "Profiles", :controller => "profiles"
+ # # => Profiles
+ #
+ # Classes and ids for CSS are easy to produce:
+ #
+ # link_to "Articles", articles_path, :id => "news", :class => "article"
+ # # => Articles
+ #
+ # Be careful when using the older argument style, as an extra literal hash is needed:
+ #
+ # link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"
+ # # => Articles
+ #
+ # Leaving the hash off gives the wrong link:
+ #
+ # link_to "WRONG!", :controller => "articles", :id => "news", :class => "article"
+ # # => WRONG!
+ #
+ # +link_to+ can also produce links with anchors or query strings:
+ #
+ # link_to "Comment wall", profile_path(@profile, :anchor => "wall")
+ # # => Comment wall
+ #
+ # link_to "Ruby on Rails search", :controller => "searches", :query => "ruby on rails"
+ # # => Ruby on Rails search
+ #
+ # link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux")
+ # # => Nonsense search
+ #
+ # The three options specfic to +link_to+ (:confirm, :popup, and :method) are used as follows:
+ #
# link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?"
# # => Visit Other Site
#
# link_to "Help", { :action => "help" }, :popup => true
# # => Help
#
- # link_to "View Image", { :action => "view" }, :popup => ['new_window_name', 'height=300,width=600']
- # # => View Image
+ # link_to "View Image", @image, :popup => ['new_window_name', 'height=300,width=600']
+ # # => View Image
#
- # link_to "Delete Image", { :action => "delete", :id => @image.id }, :confirm => "Are you sure?", :method => :delete
- # # => "Are you sure?", :method => :delete
+ # # => Delete Image
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 9b936863bad..cd526a52a73 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -12,7 +12,7 @@
change_table :videos do |t|
t.timestamps # adds created_at, updated_at
- t.belongs_to :goat # add goat_id integer
+ t.belongs_to :goat # adds goat_id integer
t.string :name, :email, :limit => 20 # adds name and email both with a 20 char limit
t.remove :name, :email # removes the name and email columns
end
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index c17e35f5e0f..95caf686925 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -753,6 +753,8 @@ module ActiveRecord
# * :source - Specifies the source association name used by has_one :through queries. Only use it if the name cannot be
# inferred from the association. has_one :favorite, :through => :favorites will look for a
# :favorite on Favorite, unless a :source is given.
+ # * :source_type - Specifies type of the source association used by has_one :through queries where the source
+ # association is a polymorphic +belongs_to+.
# * :readonly - If true, the associated object is readonly through the association.
#
# Option examples:
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 2db27226f22..c2604894a88 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -16,16 +16,20 @@ module ActiveRecord
# Declare and check for suffixed attribute methods.
module ClassMethods
- # Declare a method available for all attributes with the given suffix.
- # Uses method_missing and respond_to? to rewrite the method
+ # Declares a method available for all attributes with the given suffix.
+ # Uses +method_missing+ and respond_to? to rewrite the method
+ #
# #{attr}#{suffix}(*args, &block)
+ #
# to
+ #
# attribute#{suffix}(#{attr}, *args, &block)
#
- # An attribute#{suffix} instance method must exist and accept at least
- # the attr argument.
+ # An attribute#{suffix} instance method must exist and accept at least
+ # the +attr+ argument.
#
# For example:
+ #
# class Person < ActiveRecord::Base
# attribute_method_suffix '_changed?'
#
@@ -60,8 +64,8 @@ module ActiveRecord
!generated_methods.empty?
end
- # generates all the attribute related methods for columns in the database
- # accessors, mutators and query methods
+ # Generates all the attribute related methods for columns in the database
+ # accessors, mutators and query methods.
def define_attribute_methods
return if generated_methods?
columns_hash.each do |name, column|
@@ -89,8 +93,9 @@ module ActiveRecord
end
end
- # Check to see if the method is defined in the model or any of its subclasses that also derive from ActiveRecord.
- # Raise DangerousAttributeError if the method is defined by ActiveRecord though.
+ # Checks whether the method is defined in the model or any of its subclasses
+ # that also derive from ActiveRecord. Raises DangerousAttributeError if the
+ # method is defined by Active Record though.
def instance_method_already_implemented?(method_name)
method_name = method_name.to_s
return true if method_name =~ /^id(=$|\?$|$)/
@@ -104,17 +109,19 @@ module ActiveRecord
# +cache_attributes+ allows you to declare which converted attribute values should
# be cached. Usually caching only pays off for attributes with expensive conversion
- # methods, like date columns (e.g. created_at, updated_at).
+ # methods, like time related columns (e.g. +created_at+, +updated_at+).
def cache_attributes(*attribute_names)
attribute_names.each {|attr| cached_attributes << attr.to_s}
end
- # returns the attributes where
+ # Returns the attributes which are cached. By default time related columns
+ # with datatype :datetime, :timestamp, :time, :date are cached.
def cached_attributes
@cached_attributes ||=
columns.select{|c| attribute_types_cached_by_default.include?(c.type)}.map(&:name).to_set
end
+ # Returns +true+ if the provided attribute is being cached.
def cache_attribute?(attr_name)
cached_attributes.include?(attr_name)
end
@@ -210,14 +217,14 @@ module ActiveRecord
end # ClassMethods
- # Allows access to the object attributes, which are held in the @attributes hash, as though they
+ # Allows access to the object attributes, which are held in the @attributes hash, as though they
# were first-class methods. So a Person class with a name attribute can use Person#name and
# Person#name= and never directly use the attributes hash -- except for multiple assigns with
# ActiveRecord#attributes=. A Milestone class can also ask Milestone#completed? to test that
- # the completed attribute is not nil or 0.
+ # the completed attribute is not +nil+ or 0.
#
# It's also possible to instantiate related objects, so a Client class belonging to the clients
- # table with a master_id foreign key can instantiate master through Client#master.
+ # table with a +master_id+ foreign key can instantiate master through Client#master.
def method_missing(method_id, *args, &block)
method_name = method_id.to_s
@@ -288,7 +295,7 @@ module ActiveRecord
# Updates the attribute identified by attr_name with the specified +value+. Empty strings for fixnum and float
- # columns are turned into nil.
+ # columns are turned into +nil+.
def write_attribute(attr_name, value)
attr_name = attr_name.to_s
@attributes_cache.delete(attr_name)
@@ -319,8 +326,9 @@ module ActiveRecord
end
end
- # A Person object with a name attribute can ask person.respond_to?("name"), person.respond_to?("name="), and
- # person.respond_to?("name?") which will all return true.
+ # A Person object with a name attribute can ask person.respond_to?("name"),
+ # person.respond_to?("name="), and person.respond_to?("name?")
+ # which will all return +true+.
alias :respond_to_without_attributes? :respond_to?
def respond_to?(method, include_priv = false)
method_name = method.to_s
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index d73ffc3da6a..fdb18b234c4 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -18,11 +18,11 @@ module ActiveRecord
#
# +name+ is the column's name, as in supplier_id int(11).
# +default+ is the type-casted default value, such as sales_stage varchar(20) default 'new'.
- # +sql_type+ is only used to extract the column's length, if necessary. For example, company_name varchar(60).
+ # +sql_type+ is only used to extract the column's length, if necessary. For example, company_name varchar(60).
# +null+ determines if this column allows +NULL+ values.
def initialize(name, default, sql_type = nil, null = true)
@name, @sql_type, @null = name, sql_type, null
- @limit, @precision, @scale = extract_limit(sql_type), extract_precision(sql_type), extract_scale(sql_type)
+ @limit, @precision, @scale = extract_limit(sql_type), extract_precision(sql_type), extract_scale(sql_type)
@type = simplified_type(sql_type)
@default = extract_default(default)
@@ -172,7 +172,7 @@ module ActiveRecord
def new_time(year, mon, mday, hour, min, sec, microsec)
# Treat 0000-00-00 00:00:00 as nil.
return nil if year.nil? || year == 0
-
+
Time.time_with_datetime_fallback(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil
end
@@ -250,11 +250,11 @@ module ActiveRecord
end
class ColumnDefinition < Struct.new(:base, :name, :type, :limit, :precision, :scale, :default, :null) #:nodoc:
-
+
def sql_type
base.type_to_sql(type.to_sym, limit, precision, scale) rescue type
end
-
+
def to_sql
column_sql = "#{base.quote_column_name(name)} #{sql_type}"
add_column_options!(column_sql, :null => null, :default => default) unless type.to_sym == :primary_key
@@ -309,39 +309,39 @@ module ActiveRecord
# * :default -
# The column's default value. Use nil for NULL.
# * :null -
- # Allows or disallows +NULL+ values in the column. This option could
+ # Allows or disallows +NULL+ values in the column. This option could
# have been named :null_allowed.
# * :precision -
- # Specifies the precision for a :decimal column.
+ # Specifies the precision for a :decimal column.
# * :scale -
- # Specifies the scale for a :decimal column.
+ # Specifies the scale for a :decimal column.
#
# Please be aware of different RDBMS implementations behavior with
# :decimal columns:
# * The SQL standard says the default scale should be 0, :scale <=
# :precision, and makes no comments about the requirements of
# :precision.
- # * MySQL: :precision [1..63], :scale [0..30].
+ # * MySQL: :precision [1..63], :scale [0..30].
# Default is (10,0).
- # * PostgreSQL: :precision [1..infinity],
+ # * PostgreSQL: :precision [1..infinity],
# :scale [0..infinity]. No default.
- # * SQLite2: Any :precision and :scale may be used.
+ # * SQLite2: Any :precision and :scale may be used.
# Internal storage as strings. No default.
# * SQLite3: No restrictions on :precision and :scale,
# but the maximum supported :precision is 16. No default.
- # * Oracle: :precision [1..38], :scale [-84..127].
+ # * Oracle: :precision [1..38], :scale [-84..127].
# Default is (38,0).
- # * DB2: :precision [1..63], :scale [0..62].
+ # * DB2: :precision [1..63], :scale [0..62].
# Default unknown.
- # * Firebird: :precision [1..18], :scale [0..18].
+ # * Firebird: :precision [1..18], :scale [0..18].
# Default (9,0). Internal types NUMERIC and DECIMAL have different
# storage rules, decimal being better.
- # * FrontBase?: :precision [1..38], :scale [0..38].
+ # * FrontBase?: :precision [1..38], :scale [0..38].
# Default (38,0). WARNING Max :precision/:scale for
# NUMERIC is 19, and DECIMAL is 38.
- # * SqlServer?: :precision [1..38], :scale [0..38].
+ # * SqlServer?: :precision [1..38], :scale [0..38].
# Default (38,0).
- # * Sybase: :precision [1..38], :scale [0..38].
+ # * Sybase: :precision [1..38], :scale [0..38].
# Default (38,0).
# * OpenBase?: Documentation unclear. Claims storage in double.
#
@@ -394,7 +394,7 @@ module ActiveRecord
# t.timestamps
# end
#
- # There's a short-hand method for each of the type values declared at the top. And then there's
+ # There's a short-hand method for each of the type values declared at the top. And then there's
# TableDefinition#timestamps that'll add created_at and updated_at as datetimes.
#
# TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
@@ -434,13 +434,13 @@ module ActiveRecord
def #{column_type}(*args)
options = args.extract_options!
column_names = args
-
+
column_names.each { |name| column(name, '#{column_type}', options) }
end
EOV
end
-
- # Appends :datetime columns :created_at and
+
+ # Appends :datetime columns :created_at and
# :updated_at to the table.
def timestamps
column(:created_at, :datetime)
@@ -458,7 +458,7 @@ module ActiveRecord
alias :belongs_to :references
# Returns a String whose contents are the column definitions
- # concatenated together. This string can then be prepended and appended to
+ # concatenated together. This string can then be prepended and appended to
# to generate the final SQL to create the table.
def to_sql
@columns * ', '
@@ -510,15 +510,15 @@ module ActiveRecord
# Adds a new column to the named table.
# See TableDefinition#column for details of the options you can use.
- # ===== Examples
- # ====== Creating a simple columns
+ # ===== Example
+ # ====== Creating a simple column
# t.column(:name, :string)
def column(column_name, type, options = {})
@base.add_column(@table_name, column_name, type, options)
end
- # Adds a new index to the table. +column_name+ can be a single Symbol, or
- # an Array of Symbols. See SchemaStatements#add_index
+ # Adds a new index to the table. +column_name+ can be a single Symbol, or
+ # an Array of Symbols. See SchemaStatements#add_index
#
# ===== Examples
# ====== Creating a simple index
@@ -531,8 +531,8 @@ module ActiveRecord
@base.add_index(@table_name, column_name, options)
end
- # Adds timestamps (created_at and updated_at) columns to the table. See SchemaStatements#timestamps
- # ===== Examples
+ # Adds timestamps (created_at and updated_at) columns to the table. See SchemaStatements#add_timestamps
+ # ===== Example
# t.timestamps
def timestamps
@base.add_timestamps(@table_name)
@@ -547,7 +547,7 @@ module ActiveRecord
@base.change_column(@table_name, column_name, type, options)
end
- # Sets a new default value for a column. See
+ # Sets a new default value for a column. See SchemaStatements#change_column_default
# ===== Examples
# t.change_default(:qualification, 'new')
# t.change_default(:authorized, 1)
@@ -559,27 +559,27 @@ module ActiveRecord
# ===== Examples
# t.remove(:qualification)
# t.remove(:qualification, :experience)
- # t.removes(:qualification, :experience)
def remove(*column_names)
@base.remove_column(@table_name, column_names)
end
- # Remove the given index from the table.
+ # Removes the given index from the table.
#
- # Remove the suppliers_name_index in the suppliers table.
+ # ===== Examples
+ # ====== Remove the suppliers_name_index in the suppliers table
# t.remove_index :name
- # Remove the index named accounts_branch_id_index in the accounts table.
+ # ====== Remove the index named accounts_branch_id_index in the accounts table
# t.remove_index :column => :branch_id
- # Remove the index named accounts_branch_id_party_id_index in the accounts table.
+ # ====== Remove the index named accounts_branch_id_party_id_index in the accounts table
# t.remove_index :column => [:branch_id, :party_id]
- # Remove the index named by_branch_party in the accounts table.
+ # ====== Remove the index named by_branch_party in the accounts table
# t.remove_index :name => :by_branch_party
def remove_index(options = {})
@base.remove_index(@table_name, options)
end
# Removes the timestamp columns (created_at and updated_at) from the table.
- # ===== Examples
+ # ===== Example
# t.remove_timestamps
def remove_timestamps
@base.remove_timestamps(@table_name)
@@ -592,12 +592,11 @@ module ActiveRecord
@base.rename_column(@table_name, column_name, new_column_name)
end
- # Adds a reference. Optionally adds a +type+ column. reference,
- # references and belongs_to are all acceptable
- # ===== Example
+ # Adds a reference. Optionally adds a +type+ column.
+ # references and belongs_to are acceptable.
+ # ===== Examples
# t.references(:goat)
# t.references(:goat, :polymorphic => true)
- # t.references(:goat)
# t.belongs_to(:goat)
def references(*args)
options = args.extract_options!
@@ -609,12 +608,11 @@ module ActiveRecord
end
alias :belongs_to :references
- # Adds a reference. Optionally removes a +type+ column. remove_reference,
- # remove_references and remove_belongs_to are all acceptable
- # ===== Example
- # t.remove_reference(:goat)
- # t.remove_reference(:goat, :polymorphic => true)
+ # Removes a reference. Optionally removes a +type+ column.
+ # remove_references and remove_belongs_to are acceptable.
+ # ===== Examples
# t.remove_references(:goat)
+ # t.remove_references(:goat, :polymorphic => true)
# t.remove_belongs_to(:goat)
def remove_references(*args)
options = args.extract_options!
@@ -627,7 +625,7 @@ module ActiveRecord
alias :remove_belongs_to :remove_references
# Adds a column or columns of a specified type
- # ===== Example
+ # ===== Examples
# t.string(:goat)
# t.string(:goat, :sheep)
%w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index 1594be40e29..ac24e920fe1 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -13,7 +13,7 @@ module ActiveRecord
255
end
- # Truncates a table alias according to the limits of the current adapter.
+ # Truncates a table alias according to the limits of the current adapter.
def table_alias_for(table_name)
table_name[0..table_alias_length-1].gsub(/\./, '_')
end
@@ -152,7 +152,7 @@ module ActiveRecord
# t.remove :company
# end
#
- # ====== Remove a column
+ # ====== Remove several columns
# change_table(:suppliers) do |t|
# t.remove :company_id
# t.remove :width, :height
@@ -168,7 +168,7 @@ module ActiveRecord
def change_table(table_name)
yield Table.new(table_name, self)
end
-
+
# Renames a table.
# ===== Example
# rename_table('octopuses', 'octopi')
@@ -199,7 +199,7 @@ module ActiveRecord
end
end
alias :remove_columns :remove_column
-
+
# Changes the column's definition according to the new options.
# See TableDefinition#column for details of the options you can use.
# ===== Examples
@@ -389,7 +389,7 @@ module ActiveRecord
def distinct(columns, order_by)
"DISTINCT #{columns}"
end
-
+
# ORDER BY clause for the passed order option.
# PostgreSQL overrides this due to its stricter standards compliance.
def add_order_by_for_association_limiting!(sql, options)
@@ -401,17 +401,17 @@ module ActiveRecord
# add_timestamps(:suppliers)
def add_timestamps(table_name)
add_column table_name, :created_at, :datetime
- add_column table_name, :updated_at, :datetime
+ add_column table_name, :updated_at, :datetime
end
-
+
# Removes the timestamp columns (created_at and updated_at) from the table definition.
# ===== Examples
# remove_timestamps(:suppliers)
def remove_timestamps(table_name)
- remove_column table_name, :updated_at
- remove_column table_name, :created_at
+ remove_column table_name, :updated_at
+ remove_column table_name, :created_at
end
-
+
protected
def options_include_default?(options)
options.include?(:default) && !(options[:null] == false && options[:default].nil?)
diff --git a/activesupport/lib/active_support/core_ext/module/attr_internal.rb b/activesupport/lib/active_support/core_ext/module/attr_internal.rb
index e0be31090c3..b66c0d75005 100644
--- a/activesupport/lib/active_support/core_ext/module/attr_internal.rb
+++ b/activesupport/lib/active_support/core_ext/module/attr_internal.rb
@@ -1,19 +1,19 @@
class Module
- # Declare an attribute reader backed by an internally-named instance variable.
+ # Declares an attribute reader backed by an internally-named instance variable.
def attr_internal_reader(*attrs)
attrs.each do |attr|
module_eval "def #{attr}() #{attr_internal_ivar_name(attr)} end"
end
end
- # Declare an attribute writer backed by an internally-named instance variable.
+ # Declares an attribute writer backed by an internally-named instance variable.
def attr_internal_writer(*attrs)
attrs.each do |attr|
module_eval "def #{attr}=(v) #{attr_internal_ivar_name(attr)} = v end"
end
end
- # Declare an attribute reader and writer backed by an internally-named instance
+ # Declares an attribute reader and writer backed by an internally-named instance
# variable.
def attr_internal_accessor(*attrs)
attr_internal_reader(*attrs)
diff --git a/activesupport/lib/active_support/core_ext/range/conversions.rb b/activesupport/lib/active_support/core_ext/range/conversions.rb
index 8d757646d34..932bdedad36 100644
--- a/activesupport/lib/active_support/core_ext/range/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/range/conversions.rb
@@ -15,10 +15,9 @@ module ActiveSupport #:nodoc:
end
# Gives a human readable format of the range.
#
- # Example:
+ # ==== Example:
#
- # >> [1..100].to_formatted_s
- # => "1..100"
+ # [1..100].to_formatted_s # => "1..100"
def to_formatted_s(format = :default)
RANGE_FORMATS[format] ? RANGE_FORMATS[format].call(first, last) : to_default_s
end
diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb
index 68fbf3da352..0fd44324bb1 100644
--- a/activesupport/lib/active_support/inflector.rb
+++ b/activesupport/lib/active_support/inflector.rb
@@ -92,6 +92,13 @@ module Inflector
extend self
+ # Yields a singleton instance of Inflector::Inflections so you can specify additional
+ # inflector rules.
+ #
+ # Example:
+ # Inflector.inflections do |inflect|
+ # inflect.uncountable "rails"
+ # end
def inflections
if block_given?
yield Inflections.instance
diff --git a/railties/README b/railties/README
index b5f4eee4b7c..2af0fb1133d 100644
--- a/railties/README
+++ b/railties/README
@@ -145,7 +145,9 @@ and also on programming in general.
Debugger support is available through the debugger command when you start your Mongrel or
Webrick server with --debugger. This means that you can break out of execution at any point
-in the code, investigate and change the model, AND then resume execution! Example:
+in the code, investigate and change the model, AND then resume execution!
+You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'
+Example:
class WeblogController < ActionController::Base
def index
@@ -183,6 +185,13 @@ Passing an argument will specify a different environment, like script/consol
To reload your controllers and models after launching the console run reload!
+== dbconsole
+
+You can go to the command line of your database directly through script/dbconsole.
+You would be connected to the database with the credentials defined in database.yml.
+Starting the script without arguments will connect you to the development database. Passing an
+argument will connect you to a different database, like script/dbconsole production.
+Currently works for mysql, postgresql and sqlite.
== Description of Contents
@@ -200,13 +209,13 @@ app/models
app/views
Holds the template files for the view that should be named like
- weblogs/index.erb for the WeblogsController#index action. All views use eRuby
+ weblogs/index.html.erb for the WeblogsController#index action. All views use eRuby
syntax.
app/views/layouts
Holds the template files for layouts to be used with views. This models the common
header/footer method of wrapping views. In your views, define a layout using the
- layout :default and create a file named default.erb. Inside default.erb,
+ layout :default and create a file named default.html.erb. Inside default.html.erb,
call <% yield %> to render the view using this layout.
app/helpers
@@ -243,4 +252,5 @@ test
vendor
External libraries that the application depends on. Also includes the plugins subdirectory.
+ If the app has frozen rails, those gems also go here, under vendor/rails/.
This directory is in the load path.
diff --git a/railties/configs/initializers/new_rails_defaults.rb b/railties/configs/initializers/new_rails_defaults.rb
index b8f0e2cac23..1a718608aef 100644
--- a/railties/configs/initializers/new_rails_defaults.rb
+++ b/railties/configs/initializers/new_rails_defaults.rb
@@ -1,4 +1,4 @@
-# These settins change the behavior of Rails 2 apps and will be defaults
+# These settings change the behavior of Rails 2 apps and will be defaults
# for Rails 3. You can remove this initializer when Rails 3 is released.
# Only save the attributes that have changed since the record was loaded.
diff --git a/railties/lib/rails_generator/generators/components/migration/USAGE b/railties/lib/rails_generator/generators/components/migration/USAGE
index 3e914a5d7b0..b83c657963b 100644
--- a/railties/lib/rails_generator/generators/components/migration/USAGE
+++ b/railties/lib/rails_generator/generators/components/migration/USAGE
@@ -2,7 +2,7 @@ Description:
Stubs out a new database migration. Pass the migration name, either
CamelCased or under_scored, and an optional list of attribute pairs as arguments.
- A migration class is generated in db/migrate prefixed by the latest migration number.
+ A migration class is generated in db/migrate prefixed by a timestamp of the current date and time.
You can name your migration in either of these formats to generate add/remove
column lines from supplied attributes: AddColumnsToTable or RemoveColumnsFromTable
@@ -10,12 +10,12 @@ Description:
Example:
`./script/generate migration AddSslFlag`
- With 4 existing migrations, this creates the AddSslFlag migration in
- db/migrate/005_add_ssl_flag.rb
+ If the current date is May 14, 2008 and the current time 09:09:12, this creates the AddSslFlag migration
+ db/migrate/20080514090912_add_ssl_flag.rb
`./script/generate migration AddTitleBodyToPost title:string body:text published:boolean`
- This will create the AddTitleBodyToPost in db/migrate/005_add_title_body_to_post.rb with
+ This will create the AddTitleBodyToPost in db/migrate/20080514090912_add_title_body_to_post.rb with
this in the Up migration:
add_column :posts, :title, :string
diff --git a/railties/lib/source_annotation_extractor.rb b/railties/lib/source_annotation_extractor.rb
index 8844226536b..591fd6f6bd3 100644
--- a/railties/lib/source_annotation_extractor.rb
+++ b/railties/lib/source_annotation_extractor.rb
@@ -1,5 +1,26 @@
+# Implements the logic behind the rake tasks for annotations like
+#
+# rake notes
+# rake notes:optimize
+#
+# and friends. See rake -T notes and railties/lib/tasks/annotations.rake.
+#
+# Annotation objects are triplets :line, :tag, :text that
+# represent the line where the annotation lives, its tag, and its text. Note
+# the filename is not stored.
+#
+# Annotations are looked for in comments and modulus whitespace they have to
+# start with the tag optionally followed by a colon. Everything up to the end
+# of the line (or closing ERb comment tag) is considered to be their text.
class SourceAnnotationExtractor
class Annotation < Struct.new(:line, :tag, :text)
+
+ # Returns a representation of the annotation that looks like this:
+ #
+ # [126] [TODO] This algorithm is simple and clearly correct, make it faster.
+ #
+ # If +options+ has a flag :tag the tag is shown as in the example above.
+ # Otherwise the string contains just line and text.
def to_s(options={})
s = "[%3d] " % line
s << "[#{tag}] " if options[:tag]
@@ -7,6 +28,12 @@ class SourceAnnotationExtractor
end
end
+ # Prints all annotations with tag +tag+ under the root directories +app+, +lib+,
+ # and +test+ (recursively). Only filenames with extension +.builder+, +.rb+,
+ # +.rxml+, +.rjs+, +.rhtml+, or +.erb+ are taken into account. The +options+
+ # hash is passed to each annotation's +to_s+.
+ #
+ # This class method is the single entry point for the rake tasks.
def self.enumerate(tag, options={})
extractor = new(tag)
extractor.display(extractor.find, options)
@@ -18,10 +45,18 @@ class SourceAnnotationExtractor
@tag = tag
end
+ # Returns a hash that maps filenames under +dirs+ (recursively) to arrays
+ # with their annotations. Only files with annotations are included, and only
+ # those with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, and +.erb+
+ # are taken into account.
def find(dirs=%w(app lib test))
dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
end
+ # Returns a hash that maps filenames under +dir+ (recursively) to arrays
+ # with their annotations. Only files with annotations are included, and only
+ # those with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, and +.erb+
+ # are taken into account.
def find_in(dir)
results = {}
@@ -40,6 +75,9 @@ class SourceAnnotationExtractor
results
end
+ # If +file+ is the filename of a file that contains annotations this method returns
+ # a hash with a single entry that maps +file+ to an array of its annotations.
+ # Otherwise it returns an empty hash.
def extract_annotations_from(file, pattern)
lineno = 0
result = File.readlines(file).inject([]) do |list, line|
@@ -50,6 +88,8 @@ class SourceAnnotationExtractor
result.empty? ? {} : { file => result }
end
+ # Prints the mapping from filenames to annotations in +results+ ordered by filename.
+ # The +options+ hash is passed to each annotation's +to_s+.
def display(results, options={})
results.keys.sort.each do |file|
puts "#{file}:"