aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Noria <fxn@hashref.com>2011-05-01 11:16:31 +0200
committerXavier Noria <fxn@hashref.com>2011-05-01 11:16:31 +0200
commit2fbf302149cf40c791ca1207a5f984cf58903397 (patch)
tree5da770d0fd31520a6264a9864b1db1412646d100
parenta0656989c47c29c87c4f243ce3695c39777c67b8 (diff)
parentb84b759ec60b5005fea183186639408fcf903450 (diff)
downloadrails-2fbf302149cf40c791ca1207a5f984cf58903397.tar.gz
rails-2fbf302149cf40c791ca1207a5f984cf58903397.tar.bz2
rails-2fbf302149cf40c791ca1207a5f984cf58903397.zip
Merge branch 'master' of git://github.com/lifo/docrails
Conflicts: railties/guides/source/contributing_to_ruby_on_rails.textile
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb2
-rw-r--r--activemodel/lib/active_model/dirty.rb2
-rw-r--r--activemodel/lib/active_model/naming.rb2
-rw-r--r--activemodel/lib/active_model/observing.rb6
-rw-r--r--activemodel/lib/active_model/translation.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb21
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb13
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb13
-rw-r--r--activerecord/lib/active_record/validations.rb6
-rw-r--r--activesupport/lib/active_support/deprecation/reporting.rb4
-rw-r--r--activesupport/lib/active_support/notifications/fanout.rb6
-rw-r--r--railties/guides/source/action_mailer_basics.textile6
-rw-r--r--railties/guides/source/active_record_querying.textile35
-rw-r--r--railties/guides/source/active_support_core_extensions.textile18
-rw-r--r--railties/guides/source/association_basics.textile31
-rw-r--r--railties/guides/source/contributing_to_ruby_on_rails.textile77
-rw-r--r--railties/guides/source/debugging_rails_applications.textile14
-rw-r--r--railties/guides/source/getting_started.textile15
-rw-r--r--railties/guides/source/migrations.textile94
-rw-r--r--railties/guides/source/routing.textile4
24 files changed, 221 insertions, 188 deletions
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
index 0fe2e6d1a6..1eadfc0390 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
@@ -128,6 +128,8 @@ module HTML
# (no parent element).
# * <tt>:empty</tt> -- Match the element only if it has no child elements,
# and no text content.
+ # * <tt>:content(string)</tt> -- Match the element only if it has <tt>string</tt>
+ # as its text content (ignoring leading and trailing whitespace).
# * <tt>:only-child</tt> -- Match the element if it is the only child (element)
# of its parent element.
# * <tt>:only-of-type</tt> -- Match the element if it is the only child (element)
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb
index 5ede78617a..3b412d3dd7 100644
--- a/activemodel/lib/active_model/dirty.rb
+++ b/activemodel/lib/active_model/dirty.rb
@@ -93,7 +93,7 @@ module ActiveModel
attribute_method_affix :prefix => 'reset_', :suffix => '!'
end
- # Do any attributes have unsaved changes?
+ # Returns true if any attribute have unsaved changes, false otherwise.
# person.changed? # => false
# person.name = 'bob'
# person.changed? # => true
diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb
index 315ccd40e9..74708692af 100644
--- a/activemodel/lib/active_model/naming.rb
+++ b/activemodel/lib/active_model/naming.rb
@@ -68,7 +68,7 @@ module ActiveModel
# BookModule::BookCover.model_name.i18n_key # => "book_module.book_cover"
#
# Providing the functionality that ActiveModel::Naming provides in your object
- # is required to pass the Active Model Lint test. So either extending the provided
+ # is required to pass the Active Model Lint test. So either extending the provided
# method below, or rolling your own is required.
module Naming
# Returns an ActiveModel::Name object for module. It can be
diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb
index c1ac4eb4af..cfe71074a5 100644
--- a/activemodel/lib/active_model/observing.rb
+++ b/activemodel/lib/active_model/observing.rb
@@ -56,6 +56,8 @@ module ActiveModel
end
# Add a new observer to the pool.
+ # The new observer needs to respond to 'update', otherwise it
+ # raises an +ArgumentError+ exception.
def add_observer(observer)
unless observer.respond_to? :update
raise ArgumentError, "observer needs to respond to `update'"
@@ -144,8 +146,8 @@ module ActiveModel
# Observers will by default be mapped to the class with which they share a
# name. So CommentObserver will be tied to observing Comment, ProductManagerObserver
# to ProductManager, and so on. If you want to name your observer differently than
- # the class you're interested in observing, you can use the Observer.observe class
- # method which takes either the concrete class (Product) or a symbol for that
+ # the class you're interested in observing, you can use the <tt>Observer.observe</tt>
+ # class method which takes either the concrete class (Product) or a symbol for that
# class (:product):
#
# class AuditObserver < ActiveModel::Observer
diff --git a/activemodel/lib/active_model/translation.rb b/activemodel/lib/active_model/translation.rb
index 920a133159..6d64c81b5f 100644
--- a/activemodel/lib/active_model/translation.rb
+++ b/activemodel/lib/active_model/translation.rb
@@ -18,12 +18,12 @@ module ActiveModel
#
# This also provides the required class methods for hooking into the
# Rails internationalization API, including being able to define a
- # class based i18n_scope and lookup_ancestors to find translations in
+ # class based +i18n_scope+ and +lookup_ancestors+ to find translations in
# parent classes.
module Translation
include ActiveModel::Naming
- # Returns the i18n_scope for the class. Overwrite if you want custom lookup.
+ # Returns the +i18n_scope+ for the class. Overwrite if you want custom lookup.
def i18n_scope
:activemodel
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index b4db1eed18..6f21cea288 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -113,7 +113,7 @@ module ActiveRecord
end
end
- # A cached lookup for table existence
+ # A cached lookup for table existence.
def table_exists?(name)
return true if @tables.key? name
@@ -135,7 +135,7 @@ module ActiveRecord
@tables.clear
end
- # Clear out internal caches for table with +table_name+
+ # Clear out internal caches for table with +table_name+.
def clear_table_cache!(table_name)
@columns.delete table_name
@columns_hash.delete table_name
@@ -193,7 +193,7 @@ module ActiveRecord
@connections = []
end
- # Clears the cache which maps classes
+ # Clears the cache which maps classes.
def clear_reloadable_connections!
@reserved_connections.each do |name, conn|
checkin conn
@@ -365,7 +365,7 @@ module ActiveRecord
@connection_pools.each_value {|pool| pool.release_connection }
end
- # Clears the cache which maps classes
+ # Clears the cache which maps classes.
def clear_reloadable_connections!
@connection_pools.each_value {|pool| pool.clear_reloadable_connections! }
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb
index 29ac9341ec..30ccb8f0a4 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb
@@ -2,52 +2,53 @@ module ActiveRecord
module ConnectionAdapters # :nodoc:
module DatabaseLimits
- # the maximum length of a table alias
+ # Returns the maximum length of a table alias.
def table_alias_length
255
end
- # the maximum length of a column name
+ # Returns the maximum length of a column name.
def column_name_length
64
end
- # the maximum length of a table name
+ # Returns the maximum length of a table name.
def table_name_length
64
end
- # the maximum length of an index name
+ # Returns the maximum length of an index name.
def index_name_length
64
end
- # the maximum number of columns per table
+ # Returns the maximum number of columns per table.
def columns_per_table
1024
end
- # the maximum number of indexes per table
+ # Returns the maximum number of indexes per table.
def indexes_per_table
16
end
- # the maximum number of columns in a multicolumn index
+ # Returns the maximum number of columns in a multicolumn index.
def columns_per_multicolumn_index
16
end
- # the maximum number of elements in an IN (x,y,z) clause. nil means no limit
+ # Returns the maximum number of elements in an IN (x,y,z) clause.
+ # nil means no limit.
def in_clause_length
nil
end
- # the maximum length of an SQL query
+ # Returns the maximum length of an SQL query.
def sql_query_length
1048575
end
- # maximum number of joins in a single query
+ # Returns maximum number of joins in a single query.
def joins_per_query
256
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index 8bae50885f..9f9c2c42cb 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -17,6 +17,10 @@ module ActiveRecord
# def tables(name = nil) end
+ # Checks to see if the table +table_name+ exists on the database.
+ #
+ # === Example
+ # table_exists?(:developers)
def table_exists?(table_name)
tables.include?(table_name.to_s)
end
@@ -24,7 +28,7 @@ module ActiveRecord
# Returns an array of indexes for the given table.
# def indexes(table_name, name = nil) end
- # Checks to see if an index exists on a table for a given index definition
+ # Checks to see if an index exists on a table for a given index definition.
#
# === Examples
# # Check an index exists
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index 8973544028..d3a054c29b 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -132,6 +132,7 @@ module ActiveRecord
ADAPTER_NAME
end
+ # Returns true, since this connection adapter supports migrations.
def supports_migrations?
true
end
@@ -140,6 +141,7 @@ module ActiveRecord
true
end
+ # Returns true, since this connection adapter supports savepoints.
def supports_savepoints?
true
end
@@ -386,6 +388,10 @@ module ActiveRecord
end
end
+ # Drops a MySQL database.
+ #
+ # Example:
+ # drop_database('sebastian_development')
def drop_database(name) #:nodoc:
execute "DROP DATABASE IF EXISTS `#{name}`"
end
@@ -416,6 +422,7 @@ module ActiveRecord
super(table_name, options)
end
+ # Returns an array of indexes for the given table.
def indexes(table_name, name = nil)
indexes = []
current_index = nil
@@ -433,6 +440,7 @@ module ActiveRecord
indexes
end
+ # Returns an array of +Mysql2Column+ objects for the table specified by +table_name+.
def columns(table_name, name = nil)
sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
columns = []
@@ -447,6 +455,10 @@ module ActiveRecord
super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB"))
end
+ # Renames a table.
+ #
+ # Example:
+ # rename_table('octopuses', 'octopi')
def rename_table(table_name, new_name)
execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
end
@@ -531,6 +543,7 @@ module ActiveRecord
variables.first['Value'] unless variables.empty?
end
+ # Returns a table's primary key and belonging sequence.
def pk_and_sequence_for(table)
keys = []
result = execute("describe #{quote_table_name(table)}")
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 356aaf0ebe..862ce852e6 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -201,13 +201,13 @@ module ActiveRecord
true
end
- # Returns +true+, since this connection adapter supports prepared statement
+ # Returns true, since this connection adapter supports prepared statement
# caching.
def supports_statement_cache?
true
end
- # Returns true.
+ # Returns true, since this connection adapter supports migrations.
def supports_migrations? #:nodoc:
true
end
@@ -217,6 +217,7 @@ module ActiveRecord
true
end
+ # Returns true, since this connection adapter supports savepoints.
def supports_savepoints? #:nodoc:
true
end
@@ -584,6 +585,7 @@ module ActiveRecord
super(table_name, options)
end
+ # Returns an array of indexes for the given table.
def indexes(table_name, name = nil)#:nodoc:
indexes = []
current_index = nil
@@ -602,6 +604,7 @@ module ActiveRecord
indexes
end
+ # Returns an array of +MysqlColumn+ objects for the table specified by +table_name+.
def columns(table_name, name = nil)#:nodoc:
sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
columns = []
@@ -615,6 +618,10 @@ module ActiveRecord
super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB"))
end
+ # Renames a table.
+ #
+ # Example:
+ # rename_table('octopuses', 'octopi')
def rename_table(table_name, new_name)
execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
end
@@ -892,6 +899,7 @@ module ActiveRecord
version[0] >= 5
end
+ # Returns the version of the connected MySQL server.
def version
@version ||= @connection.server_info.scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map { |v| v.to_i }
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 3b0d960acc..37db2be7a9 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -294,7 +294,7 @@ module ActiveRecord
NATIVE_DATABASE_TYPES
end
- # Does PostgreSQL support migrations?
+ # Returns true, since this connection adapter supports migrations.
def supports_migrations?
true
end
@@ -320,6 +320,7 @@ module ActiveRecord
true
end
+ # Returns true, since this connection adapter supports savepoints.
def supports_savepoints?
true
end
@@ -682,7 +683,7 @@ module ActiveRecord
[schema, table]
end
- # Returns the list of all indexes for a table.
+ # Returns an array of indexes for the given table.
def indexes(table_name, name = nil)
schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
result = query(<<-SQL, name)
@@ -847,6 +848,9 @@ module ActiveRecord
end
# Renames a table.
+ #
+ # Example:
+ # rename_table('octopuses', 'octopi')
def rename_table(name, new_name)
execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
end
@@ -931,7 +935,7 @@ module ActiveRecord
end
protected
- # Returns the version of the connected PostgreSQL version.
+ # Returns the version of the connected PostgreSQL server.
def postgresql_version
@connection.server_version
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 04367657ec..d2785b234a 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -58,10 +58,12 @@ module ActiveRecord
'SQLite'
end
+ # Returns true if SQLite version is '2.0.0' or greater, false otherwise.
def supports_ddl_transactions?
sqlite_version >= '2.0.0'
end
+ # Returns true if SQLite version is '3.6.8' or greater, false otherwise.
def supports_savepoints?
sqlite_version >= '3.6.8'
end
@@ -72,7 +74,7 @@ module ActiveRecord
true
end
- # Returns true.
+ # Returns true, since this connection adapter supports migrations.
def supports_migrations? #:nodoc:
true
end
@@ -86,6 +88,7 @@ module ActiveRecord
true
end
+ # Returns true if SQLite version is '3.1.6' or greater, false otherwise.
def supports_add_column?
sqlite_version >= '3.1.6'
end
@@ -103,10 +106,12 @@ module ActiveRecord
@statements.clear
end
+ # Returns true if SQLite version is '3.2.6' or greater, false otherwise.
def supports_count_distinct? #:nodoc:
sqlite_version >= '3.2.6'
end
+ # Returns true if SQLite version is '3.1.0' or greater, false otherwise.
def supports_autoincrement? #:nodoc:
sqlite_version >= '3.1.0'
end
@@ -250,6 +255,7 @@ module ActiveRecord
end
end
+ # Returns an array of +SQLiteColumn+ objects for the table specified by +table_name+.
def columns(table_name, name = nil) #:nodoc:
table_structure(table_name).map do |field|
case field["dflt_value"]
@@ -265,6 +271,7 @@ module ActiveRecord
end
end
+ # Returns an array of indexes for the given table.
def indexes(table_name, name = nil) #:nodoc:
exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", name).map do |row|
IndexDefinition.new(
@@ -288,6 +295,10 @@ module ActiveRecord
exec_query "DROP INDEX #{quote_column_name(index_name)}"
end
+ # Renames a table.
+ #
+ # Example:
+ # rename_table('octopuses', 'octopi')
def rename_table(name, new_name)
exec_query "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
end
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index d73fce9fd0..de36dd20b3 100644
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -30,7 +30,7 @@ module ActiveRecord
include ActiveModel::Validations
module ClassMethods
- # Creates an object just like Base.create but calls save! instead of save
+ # Creates an object just like Base.create but calls <tt>save!</tt> instead of +save+
# so an exception is raised if the record is invalid.
def create!(attributes = nil, &block)
if attributes.is_a?(Array)
@@ -44,13 +44,13 @@ module ActiveRecord
end
end
- # The validation process on save can be skipped by passing :validate => false. The regular Base#save method is
+ # The validation process on save can be skipped by passing <tt>:validate => false</tt>. The regular Base#save method is
# replaced with this when the validations module is mixed in, which it is by default.
def save(options={})
perform_validations(options) ? super : false
end
- # Attempts to save the record just like Base#save but will raise a RecordInvalid exception instead of returning false
+ # Attempts to save the record just like Base#save but will raise a +RecordInvalid+ exception instead of returning false
# if the record is not valid.
def save!(options={})
perform_validations(options) ? super : raise(RecordInvalid.new(self))
diff --git a/activesupport/lib/active_support/deprecation/reporting.rb b/activesupport/lib/active_support/deprecation/reporting.rb
index ced08b8783..5d7e241d1a 100644
--- a/activesupport/lib/active_support/deprecation/reporting.rb
+++ b/activesupport/lib/active_support/deprecation/reporting.rb
@@ -5,10 +5,8 @@ module ActiveSupport
# Outputs a deprecation warning to the output configured by <tt>ActiveSupport::Deprecation.behavior</tt>
#
- # Example:
- #
# ActiveSupport::Deprecation.warn("something broke!")
- # #=> "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
+ # # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
def warn(message = nil, callstack = caller)
return if silenced
deprecation_message(callstack, message).tap do |m|
diff --git a/activesupport/lib/active_support/notifications/fanout.rb b/activesupport/lib/active_support/notifications/fanout.rb
index adc34f3286..a9aa5464e9 100644
--- a/activesupport/lib/active_support/notifications/fanout.rb
+++ b/activesupport/lib/active_support/notifications/fanout.rb
@@ -1,7 +1,7 @@
module ActiveSupport
module Notifications
- # This is a default queue implementation that ships with Notifications. It
- # just pushes events to all registered log subscribers.
+ # This is a default queue implementation that ships with Notifications.
+ # It just pushes events to all registered log subscribers.
class Fanout
def initialize
@subscribers = []
@@ -33,7 +33,7 @@ module ActiveSupport
listeners_for(name).any?
end
- # This is a sync queue, so there is not waiting.
+ # This is a sync queue, so there is no waiting.
def wait
end
diff --git a/railties/guides/source/action_mailer_basics.textile b/railties/guides/source/action_mailer_basics.textile
index 56da360972..a6ff8f877d 100644
--- a/railties/guides/source/action_mailer_basics.textile
+++ b/railties/guides/source/action_mailer_basics.textile
@@ -120,7 +120,7 @@ Now that we have a user model to play with, we will just edit the +app/controlle
<ruby>
class UsersController < ApplicationController
# POST /users
- # POST /users.xml
+ # POST /users.json
def create
@user = User.new(params[:user])
@@ -130,10 +130,10 @@ class UsersController < ApplicationController
UserMailer.welcome_email(@user).deliver
format.html { redirect_to(@user, :notice => 'User was successfully created.') }
- format.xml { render :xml => @user, :status => :created, :location => @user }
+ format.json { render :json => @user, :status => :created, :location => @user }
else
format.html { render :action => "new" }
- format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
+ format.json { render :json => @user.errors, :status => :unprocessable_entity }
end
end
end
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index 2f0a51e868..579a323d57 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -56,6 +56,7 @@ The methods are:
* +select+
* +group+
* +order+
+* +reorder+
* +limit+
* +offset+
* +joins+
@@ -495,9 +496,9 @@ This will return single order objects for each day, but only for the last month.
h3. Overriding Conditions
-You can specify certain conditions to be excepted by using the +except+ method.
+h4. +except+
-For example:
+You can specify certain conditions to be excepted by using the +except+ method. For example:
<ruby>
Post.where('id > 10').limit(20).order('id asc').except(:order)
@@ -509,9 +510,9 @@ The SQL that would be executed:
SELECT * FROM posts WHERE id > 10 LIMIT 20
</sql>
-You can also override conditions using the +only+ method.
+h4. +only+
-For example:
+You can also override conditions using the +only+ method. For example:
<ruby>
Post.where('id > 10').limit(20).order('id desc').only(:order, :where)
@@ -523,6 +524,32 @@ The SQL that would be executed:
SELECT * FROM posts WHERE id > 10 ORDER BY id DESC
</sql>
+h4. +reorder+
+
+The +reorder+ method overrides the default scope order. For example:
+
+<ruby>
+class Post < ActiveRecord::Base
+ ..
+ ..
+ has_many :comments, :order => 'posted_at DESC'
+end
+
+Post.find(10).comments.reorder('name')
+</ruby>
+
+The SQL that would be executed:
+
+<sql>
+SELECT * FROM posts WHERE id = 10 ORDER BY name
+</sql>
+
+In case the +reorder+ clause is not used, the SQL executed would be:
+
+<sql>
+SELECT * FROM posts WHERE id = 10 ORDER BY posted_at DESC
+</sql>
+
h3. Readonly Objects
Active Record provides +readonly+ method on a relation to explicitly disallow modification or deletion of any of the returned object. Any attempt to alter or destroy a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception.
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index f89c83e4cd..f2170e120b 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -449,9 +449,9 @@ The predicate +in?+ tests if an object is included in another object. An +Argume
Examples of +in?+:
<ruby>
- 1.in?([1,2]) # => true
- "lo".in?("hello") # => true
- 25.in?(30..50) # => false
+1.in?([1,2]) # => true
+"lo".in?("hello") # => true
+25.in?(30..50) # => false
</ruby>
NOTE: Defined in +active_support/core_ext/object/inclusion.rb+.
@@ -541,9 +541,9 @@ The default value can be also specified with a block, which is called in the con
<ruby>
class User
attr_accessor :name, :surname
- attr_accessor_with_default(:full_name) {
- [name, surname].compact.join(" ")
- }
+ attr_accessor_with_default(:full_name) do
+ [name, surname].compact.join(" ")
+ end
end
u = User.new
@@ -1223,7 +1223,7 @@ NOTE: Defined in +active_support/core_ext/string/output_safety.rb+.
h4. +squish+
-The method +String#squish+ strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
+The method +squish+ strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
<ruby>
" \n foo\n\r \t bar \n".squish # => "foo bar"
@@ -1996,11 +1996,11 @@ Active Support augments the API of arrays to ease certain ways of accessing them
[].to(7) # => []
</ruby>
-Similarly, +from+ returns the tail from the element at the passed index on:
+Similarly, +from+ returns the tail from the element at the passed index to the end. If the index is greater than the length of the array, it returns an empty array.
<ruby>
%w(a b c d).from(2) # => %w(c d)
-%w(a b c d).from(10) # => nil
+%w(a b c d).from(10) # => []
[].from(0) # => []
</ruby>
diff --git a/railties/guides/source/association_basics.textile b/railties/guides/source/association_basics.textile
index e5b8c73c43..94dce1b97b 100644
--- a/railties/guides/source/association_basics.textile
+++ b/railties/guides/source/association_basics.textile
@@ -229,7 +229,7 @@ The corresponding migration might look like this:
<ruby>
class CreateSuppliers < ActiveRecord::Migration
- def self.up
+ def change
create_table :suppliers do |t|
t.string :name
t.timestamps
@@ -241,11 +241,6 @@ class CreateSuppliers < ActiveRecord::Migration
t.timestamps
end
end
-
- def self.down
- drop_table :accounts
- drop_table :suppliers
- end
end
</ruby>
@@ -314,7 +309,7 @@ If you have an instance of the +Picture+ model, you can get to its parent via +@
<ruby>
class CreatePictures < ActiveRecord::Migration
- def self.up
+ def change
create_table :pictures do |t|
t.string :name
t.integer :imageable_id
@@ -322,10 +317,6 @@ class CreatePictures < ActiveRecord::Migration
t.timestamps
end
end
-
- def self.down
- drop_table :pictures
- end
end
</ruby>
@@ -333,17 +324,13 @@ This migration can be simplified by using the +t.references+ form:
<ruby>
class CreatePictures < ActiveRecord::Migration
- def self.up
+ def change
create_table :pictures do |t|
t.string :name
t.references :imageable, :polymorphic => true
t.timestamps
end
end
-
- def self.down
- drop_table :pictures
- end
end
</ruby>
@@ -413,17 +400,13 @@ This declaration needs to be backed up by the proper foreign key declaration on
<ruby>
class CreateOrders < ActiveRecord::Migration
- def self.up
+ def change
create_table :orders do |t|
t.datetime :order_date
t.string :order_number
t.integer :customer_id
end
end
-
- def self.down
- drop_table :orders
- end
end
</ruby>
@@ -451,16 +434,12 @@ These need to be backed up by a migration to create the +assemblies_parts+ table
<ruby>
class CreateAssemblyPartJoinTable < ActiveRecord::Migration
- def self.up
+ def change
create_table :assemblies_parts, :id => false do |t|
t.integer :assembly_id
t.integer :part_id
end
end
-
- def self.down
- drop_table :assemblies_parts
- end
end
</ruby>
diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile
index 4f7a58f01e..d7090ef675 100644
--- a/railties/guides/source/contributing_to_ruby_on_rails.textile
+++ b/railties/guides/source/contributing_to_ruby_on_rails.textile
@@ -2,7 +2,7 @@ h2. Contributing to Ruby on Rails
This guide covers ways in which _you_ can become a part of the ongoing development of Ruby on Rails. After reading it, you should be familiar with:
-* Using Lighthouse to report issues
+* Using GitHub to report issues
* Cloning master and running the test suite
* Helping to resolve existing issues
* Contributing to the Ruby on Rails documentation
@@ -14,29 +14,25 @@ endprologue.
h3. Reporting an Issue
-Ruby on Rails uses a "Lighthouse project":http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/ to track issues (primarily bugs and contributions of new code). If you've found a bug in Ruby on Rails, this is the place to start. You'll need to create a (free) Lighthouse account in order to comment on issues or to upload patches.
+Ruby on Rails uses "GitHub Issue Tracking":https://github.com/rails/rails/issues to track issues (primarily bugs and contributions of new code). If you've found a bug in Ruby on Rails, this is the place to start. You'll need to create a (free) GitHub account in order to either submit an issue, comment on them or create pull requests.
NOTE: Bugs in the most recent released version of Ruby on Rails are likely to get the most attention. Also, the Rails core team is always interested in feedback from those who can take the time to test _edge Rails_ (the code for the version of Rails that is currently under development). Later in this guide you'll find out how to get edge Rails for testing.
h4. Creating a Bug Report
-If you've found a problem in Ruby on Rails which is not a security risk do a search in Lighthouse in case it was already reported. If you find no ticket addressing it you can "add a new one":http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/new. (See the next section for reporting security issues.)
+If you've found a problem in Ruby on Rails which is not a security risk do a search in GitHub Issues in case it was already reported. If you find no issue addressing it you can "add a new one":https://github.com/rails/rails/issues/new. (See the next section for reporting security issues.)
-At the minimum, your ticket needs a title and descriptive text. But that's only a minimum. You should include as much relevant information as possible. You need to at least post the code sample that has the issue. Even better is to include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself - and others - to replicate the bug and figure out a fix.
+At the minimum, your issue report needs a title and descriptive text. But that's only a minimum. You should include as much relevant information as possible. You need to at least post the code sample that has the issue. Even better is to include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself - and others - to replicate the bug and figure out a fix.
-You shouldn't assign the bug to a particular core developer unless you know for sure which developer will be handling that issue. The core team periodically reviews issues and assigns developers and milestones to them.
-
-You should set tags for your issue. Use the "bug" tag for a bug report, and add the "patch" tag if you are attaching a patch. Try to find some relevant tags from the existing tag list (which will appear as soon as you start typing in the "Choose some tags" textbox), rather than creating new tags.
-
-Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kind of bug, you're creating this ticket in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the ticket automatically will see any activity or that others will jump to fix it. Creating a ticket like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with a "I'm having this problem too" comment.
+Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating a issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with a "I'm having this problem too" comment.
h4. Special Treatment for Security Issues
-WARNING: Please do not report security vulnerabilities on public Lighthouse tickets. The "Rails security policy page":http://rubyonrails.org/security details the procedure to follow for security issues.
+WARNING: Please do not report security vulnerabilities with public GitHub issue reports. The "Rails security policy page":http://rubyonrails.org/security details the procedure to follow for security issues.
h4. What About Feature Requests?
-Please don't put "feature request" tickets into Lighthouse. If there's a new feature that you want to see added to Ruby on Rails, you'll need to write the code yourself - or convince someone else to partner with you to write the code. Later in this guide you'll find detailed instructions for proposing a patch to Ruby on Rails. If you enter a wishlist item in Lighthouse with no code, you can expect it to be marked "invalid" as soon as it's reviewed.
+Please don't put "feature request" items into GitHub Issues. If there's a new feature that you want to see added to Ruby on Rails, you'll need to write the code yourself - or convince someone else to partner with you to write the code. Later in this guide you'll find detailed instructions for proposing a patch to Ruby on Rails. If you enter a wishlist item in GitHub Issues with no code, you can expect it to be marked "invalid" as soon as it's reviewed.
h3. Running the Test Suite
@@ -216,11 +212,11 @@ TIP: You may want to "put your git branch name in your shell prompt":http://qugs
h3. Helping to Resolve Existing Issues
-As a next step beyond reporting issues, you can help the core team resolve existing issues. If you check the "open tickets":https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets?q=state%3Aopen list in Lighthouse, you'll find lots of issues already requiring attention. What can you do for these? Quite a bit, actually:
+As a next step beyond reporting issues, you can help the core team resolve existing issues. If you check the "Everyone's Issues":https://github.com/rails/rails/issues?sort=created&direction=desc&state=open&page=1 list in GitHub Issues, you'll find lots of issues already requiring attention. What can you do for these? Quite a bit, actually:
h4. Verifying Bug Reports
-For starters, it helps to just verify bug reports. Can you reproduce the reported issue on your own computer? If so, you can add a comment to the ticket saying that you're seeing the same thing.
+For starters, it helps to just verify bug reports. Can you reproduce the reported issue on your own computer? If so, you can add a comment to the issue saying that you're seeing the same thing.
If something is very vague, can you help squish it down into something specific? Maybe you can provide additional information to help reproduce a bug, or eliminate needless steps that aren't required to help demonstrate the problem.
@@ -230,26 +226,27 @@ Anything you can do to make bug reports more succinct or easier to reproduce is
h4. Testing Patches
-You can also help out by examining patches that have been submitted to Ruby on Rails via Lighthouse. To apply someone's changes you need to first create a dedicated branch:
+You can also help out by examining pull requests that have been submitted to Ruby on Rails via GitHub. To apply someone's changes you need to first create a dedicated branch:
<shell>
$ git checkout -b testing_branch
</shell>
-Then you can apply their patch:
+Then you can use their remote branch to update your codebase. For example, let's say the github user JohnSmith has forked and pushed to the master branch located at http://github.com/JohnSmith/rails.
<shell>
-$ git am their-patch-file.diff
+$ git remote add JohnSmith git://github.com/JohnSmith/rails.git
+$ git pull JohnSmith master
</shell>
-After applying a patch, test it out! Here are some things to think about:
+After applying their branch, test it out! Here are some things to think about:
-* Does the patch actually work?
+* Does the change actually work?
* Are you happy with the tests? Can you follow what they're testing? Are there any tests missing?
* Does it have proper documentation coverage? Should documentation elsewhere be updated?
* Do you like the implementation? Can you think of a nicer or faster way to implement a part of their change?
-Once you're happy that the patch contains a good change, comment on the Lighthouse ticket indicating your approval. Your comment should indicate that you like the change and what you like about it. Something like:
+Once you're happy that the pull request contains a good change, comment on the GitHub issue indicating your approval. Your comment should indicate that you like the change and what you like about it. Something like:
<blockquote>
I like the way you've restructured that code in generate_finder_sql, much nicer. The tests look good too.
@@ -261,7 +258,7 @@ h3. Contributing to the Rails Documentation
Ruby on Rails has two main sets of documentation: The guides help you to learn Ruby on Rails, and the API is a reference.
-You can create a ticket in Lighthouse to fix or expand documentation. However, if you're confident about your changes you can push them yourself directly via "docrails":https://github.com/lifo/docrails/tree/master. docrails is a branch with an *open commit policy* and public write access. Commits to docrails are still reviewed, but that happens after they are pushed. docrails is merged with master regularly, so you are effectively editing the Ruby on Rails documentation.
+You can create an issue in GitHub issues to fix or expand documentation. However, if you're confident about your changes you can push them yourself directly via "docrails":https://github.com/lifo/docrails/tree/master. docrails is a branch with an *open commit policy* and public write access. Commits to docrails are still reviewed, but that happens after they are pushed. docrails is merged with master regularly, so you are effectively editing the Ruby on Rails documentation.
When working with documentation, please take into account the "API Documentation Guidelines":api_documentation_guidelines.html and the "Ruby on Rails Guides Guidelines":ruby_on_rails_guides_guidelines.html.
@@ -314,20 +311,14 @@ You should not be the only person who looks at the code before you submit it. Yo
You might also want to check out the "RailsBridge BugMash":http://wiki.railsbridge.org/projects/railsbridge/wiki/BugMash as a way to get involved in a group effort to improve Rails. This can help you get started and help check your code when you're writing your first patches.
-h4. Create a Lighthouse Ticket
-
-Now create a ticket for your patch. Go to the "new ticket":http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/new page at Lighthouse. Fill in a reasonable title and description, as well as tag the ticket with the ‘patch’ tag and whatever other subject area tags make sense. Write down your ticket number, for you will need it in the following step.
-
h4. Commit Your Changes
When you're happy with the code on your computer, you need to commit the changes to git:
<shell>
-$ git commit -a -m "Here is a commit message. Closes #issue_number"
+$ git commit -a -m "Here is a commit message on what I changed in this commit"
</shell>
-NOTE: By adding 'Closes #issue_number' at the end of your commit message, the issue will automatically change its status to closed once your patch is pushed to the repository.
-
h4. Update master
It’s pretty likely that other changes to master have happened while you were working. Go get them:
@@ -346,33 +337,29 @@ $ git rebase master
No conflicts? Tests still pass? Change still seems reasonable to you? Then move on.
-h4. Create a Patch
-
-Now you can create a patch file to share with other developers (and with the core team). Still in your branch, run
+h4. Fork
-<shell>
-$ git commit -a
-$ git format-patch master --stdout > my_new_patch.diff
-</shell>
-
-Open the diff file in your text editor of choice to sanity check the results, and make sure that no unintended changes crept in.
+Navigate to the Rails "GitHub repository":https://github.com/rails/rails and press "Fork" in the upper right hand corner.
-You can also perform an extra check by applying the patch to a different dedicated branch:
+Add the new remote to your local repository on your local machine:
<shell>
-$ git checkout -b testing_branch
-$ git apply --check my_new_patch.diff
+$ git remote add mine https://&lt;your user name&gt;@github.com/&lt;your user name&gt;/rails.git
</shell>
-Please make sure the patch does not introduce whitespace errors:
+Push to your remote:
<shell>
-$ git apply --whitespace=error-all my_new_patch.diff
+$ git push mine master
</shell>
-h4. Attach your Patch to the Lighthouse Ticket
+h4. Issue a Pull Request
+
+Navigate to the Rails repository you just pushed to (e.g. https://github.com/&lt;your user name&gt;/rails) and press "Pull Request" in the upper right hand corner.
+
+Ensure the changesets you introduced are included in the "Commits" tab and that the "Files Changed" incorporate all of your changes.
-Now you need to update the ticket by attaching the patch file you just created.
+Fill in some details about your potential patch including a meaningful title. When finished, press "Send pull request." Rails Core will be notified about your submission.
h4. Get Some Feedback
@@ -390,9 +377,9 @@ All contributions, either via master or docrails, get credit in "Rails Contribut
h3. Changelog
-* April 14, 2001: Modified Contributing to the Rails Code section to add '[#ticket_number state:commited]' on patches commit messages by "Sebastian Martinez":http://wyeworks.com
+* April 29, 2011: Reflect GitHub Issues and Pull Request workflow by "Dan Pickett":http://www.enlightsolutions.com
+* April 14, 2011: Modified Contributing to the Rails Code section to add '[#ticket_number state:commited]' on patches commit messages by "Sebastian Martinez":http://wyeworks.com
* December 28, 2010: Complete revision by "Xavier Noria":credits.html#fxn
* April 6, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* August 1, 2009: Updates/amplifications by "Mike Gunderloy":credits.html#mgunderloy
* March 2, 2009: Initial draft by "Mike Gunderloy":credits.html#mgunderloy
-
diff --git a/railties/guides/source/debugging_rails_applications.textile b/railties/guides/source/debugging_rails_applications.textile
index 477ff29dbd..6f028805d6 100644
--- a/railties/guides/source/debugging_rails_applications.textile
+++ b/railties/guides/source/debugging_rails_applications.textile
@@ -279,14 +279,14 @@ This command shows you where you are in the code by printing 10 lines centered a
[1, 10] in /PathToProject/posts_controller.rb
1 class PostsController < ApplicationController
2 # GET /posts
- 3 # GET /posts.xml
+ 3 # GET /posts.json
4 def index
5 debugger
=> 6 @posts = Post.all
7
8 respond_to do |format|
9 format.html # index.html.erb
- 10 format.xml { render :xml => @posts }
+ 10 format.json { render :json => @posts }
</shell>
If you repeat the +list+ command, this time using just +l+, the next ten lines of the file will be printed out.
@@ -298,7 +298,7 @@ If you repeat the +list+ command, this time using just +l+, the next ten lines o
12 end
13
14 # GET /posts/1
- 15 # GET /posts/1.xml
+ 15 # GET /posts/1.json
16 def show
17 @post = Post.find(params[:id])
18
@@ -315,14 +315,14 @@ On the other hand, to see the previous ten lines you should type +list-+ (or +l-
[1, 10] in /PathToProject/posts_controller.rb
1 class PostsController < ApplicationController
2 # GET /posts
- 3 # GET /posts.xml
+ 3 # GET /posts.json
4 def index
5 debugger
6 @posts = Post.all
7
8 respond_to do |format|
9 format.html # index.html.erb
- 10 format.xml { render :xml => @posts }
+ 10 format.json { render :json => @posts }
</shell>
This way you can move inside the file, being able to see the code above and over the line you added the +debugger+.
@@ -333,14 +333,14 @@ Finally, to see where you are in the code again you can type +list=+
[1, 10] in /PathToProject/posts_controller.rb
1 class PostsController < ApplicationController
2 # GET /posts
- 3 # GET /posts.xml
+ 3 # GET /posts.json
4 def index
5 debugger
=> 6 @posts = Post.all
7
8 respond_to do |format|
9 format.html # index.html.erb
- 10 format.xml { render :xml => @posts }
+ 10 format.json { render :json => @posts }
</shell>
h4. The Context
diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile
index 366df9cd84..a826a33120 100644
--- a/railties/guides/source/getting_started.textile
+++ b/railties/guides/source/getting_started.textile
@@ -378,7 +378,7 @@ If you look in the +db/migrate/20100207214725_create_posts.rb+ file (remember, y
<ruby>
class CreatePosts < ActiveRecord::Migration
- def self.up
+ def change
create_table :posts do |t|
t.string :name
t.string :title
@@ -387,14 +387,10 @@ class CreatePosts < ActiveRecord::Migration
t.timestamps
end
end
-
- def self.down
- drop_table :posts
- end
end
</ruby>
-The above migration creates two methods, +up+, called when you run this migration into the database, and +down+ in case you need to reverse the changes made by this migration at a later date. The +up+ command in this case creates a +posts+ table with two string columns and a text column. It also creates two timestamp fields to track record creation and updating. More information about Rails migrations can be found in the "Rails Database Migrations":migrations.html guide.
+The above migration creates a method name +change+ which will be called when you run this migration. The action defined in that method is also reversible, which means Rails knows how to reverse the change made by this migration, in case you want to reverse it at later date. By default, when you run this migration it will creates a +posts+ table with two string columns and a text column. It also creates two timestamp fields to track record creation and updating. More information about Rails migrations can be found in the "Rails Database Migrations":migrations.html guide.
At this point, you can use a rake command to run the migration:
@@ -807,7 +803,7 @@ In addition to the model, Rails has also made a migration to create the correspo
<ruby>
class CreateComments < ActiveRecord::Migration
- def self.up
+ def change
create_table :comments do |t|
t.string :commenter
t.text :body
@@ -818,10 +814,6 @@ class CreateComments < ActiveRecord::Migration
add_index :comments, :post_id
end
-
- def self.down
- drop_table :comments
- end
end
</ruby>
@@ -1458,6 +1450,7 @@ Two very common sources of data that are not UTF-8:
h3. Changelog
+* April 26, 2011: Changed migration code from +up+, +down+ pair to +change+ method "Prem Sichanugrist":"http://sikachu.com"
* April 11, 2011: Changed scaffold_controller generator to create format block for JSON instead of XML "Sebastian Martinez":http://www.wyeworks.com
* August 30, 2010: Minor editing after Rails 3 release by "Joost Baaij":http://www.spacebabies.nl
* July 12, 2010: Fixes, editing and updating of code samples by "Jaime Iniesta":http://jaimeiniesta.com
diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile
index bf5d4d3e4d..27f8a9303e 100644
--- a/railties/guides/source/migrations.textile
+++ b/railties/guides/source/migrations.textile
@@ -21,7 +21,7 @@ Before I dive into the details of a migration, here are a few examples of the so
<ruby>
class CreateProducts < ActiveRecord::Migration
- def self.up
+ def up
create_table :products do |t|
t.string :name
t.text :description
@@ -30,7 +30,7 @@ class CreateProducts < ActiveRecord::Migration
end
end
- def self.down
+ def down
drop_table :products
end
end
@@ -42,14 +42,14 @@ Migrations are not limited to changing the schema. You can also use them to fix
<ruby>
class AddReceiveNewsletterToUsers < ActiveRecord::Migration
- def self.up
+ def up
change_table :users do |t|
t.boolean :receive_newsletter, :default => false
end
User.update_all ["receive_newsletter = ?", true]
end
- def self.down
+ def down
remove_column :users, :receive_newsletter
end
end
@@ -58,6 +58,21 @@ end
This migration adds a +receive_newsletter+ column to the +users+ table. We want it to default to +false+ for new users, but existing users are considered
to have already opted in, so we use the User model to set the flag to +true+ for existing users.
+Rails 3.1 makes migrations smarter by providing a new <tt>change</tt> method. This method is preferred for writing constructive migrations (adding columns or tables). The migration knows how to migrate your database and reverse it when the migration is rolled back without the need to write a separate +down+ method.
+
+<ruby>
+class CreateProducts < ActiveRecord::Migration
+ def change
+ create_table :products do |t|
+ t.string :name
+ t.text :description
+
+ t.timestamps
+ end
+ end
+end
+</ruby>
+
NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations.
h4. Migrations are Classes
@@ -116,7 +131,7 @@ will create a migration that looks like this
<ruby>
class CreateProducts < ActiveRecord::Migration
- def self.up
+ def change
create_table :products do |t|
t.string :name
t.text :description
@@ -124,10 +139,6 @@ class CreateProducts < ActiveRecord::Migration
t.timestamps
end
end
-
- def self.down
- drop_table :products
- end
end
</ruby>
@@ -146,10 +157,7 @@ This will create an empty but appropriately named migration:
<ruby>
class AddPartNumberToProducts < ActiveRecord::Migration
- def self.up
- end
-
- def self.down
+ def change
end
end
</ruby>
@@ -164,13 +172,9 @@ will generate
<ruby>
class AddPartNumberToProducts < ActiveRecord::Migration
- def self.up
+ def change
add_column :products, :part_number, :string
end
-
- def self.down
- remove_column :products, :part_number
- end
end
</ruby>
@@ -184,11 +188,11 @@ generates
<ruby>
class RemovePartNumberFromProducts < ActiveRecord::Migration
- def self.up
+ def up
remove_column :products, :part_number
end
- def self.down
+ def down
add_column :products, :part_number, :string
end
end
@@ -204,20 +208,17 @@ generates
<ruby>
class AddDetailsToProducts < ActiveRecord::Migration
- def self.up
+ def change
add_column :products, :part_number, :string
add_column :products, :price, :decimal
end
-
- def self.down
- remove_column :products, :price
- remove_column :products, :part_number
- end
end
</ruby>
As always, what has been generated for you is just a starting point. You can add or remove from it as you see fit.
+NOTE: The generated migration file for destructive migrations will still be old-style using the +up+ and +down+ methods. This is because Rails doesn't know the original data types defined when you made the original changes.
+
h3. Writing a Migration
Once you have created your migration using one of the generators it's time to get to work!
@@ -337,6 +338,21 @@ If the helpers provided by Active Record aren't enough you can use the +execute+
For more details and examples of individual methods check the API documentation, in particular the documentation for "<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html (which provides the methods available in the +up+ and +down+ methods), "<tt>ActiveRecord::ConnectionAdapters::TableDefinition</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html (which provides the methods available on the object yielded by +create_table+) and "<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html (which provides the methods available on the object yielded by +change_table+).
+h4. Writing Your +change+ Method
+
+The +change+ method removes the need to write both +up+ and +down+ methods in those cases that Rails know how to revert the changes automatically. Currently, the +change+ method supports only these migration definitions:
+
+* +add_column+
+* +add_index+
+* +add_timestamp+
+* +create_table+
+* +remove_timestamps+
+* +rename_column+
+* +rename_index+
+* +rename_table+
+
+If you're going to use other methods, you'll have to write the +up+ and +down+ methods normally.
+
h4. Writing Your +down+ Method
The +down+ method of your migration should revert the transformations done by the +up+ method. In other words the database schema should be unchanged if you do an +up+ followed by a +down+. For example if you create a table in the +up+ method you should drop it in the +down+ method. It is wise to do things in precisely the reverse order to in the +up+ method. For example
@@ -344,7 +360,7 @@ The +down+ method of your migration should revert the transformations done by th
<ruby>
class ExampleMigration < ActiveRecord::Migration
- def self.up
+ def up
create_table :products do |t|
t.references :category
end
@@ -361,7 +377,7 @@ class ExampleMigration < ActiveRecord::Migration
rename_column :users, :email, :email_address
end
- def self.down
+ def down
rename_column :users, :email_address, :email
remove_column :users, :home_page_url
execute "ALTER TABLE products DROP FOREIGN KEY fk_products_categories"
@@ -369,9 +385,8 @@ class ExampleMigration < ActiveRecord::Migration
end
end
</ruby>
-Sometimes your migration will do something which is just plain irreversible, for example it might destroy some data. In cases like those when you can't reverse the migration you can raise +IrreversibleMigration+ from your +down+ method. If someone tries to revert your migration an error message will be
-displayed saying that it can't be done.
+Sometimes your migration will do something which is just plain irreversible, for example it might destroy some data. In cases like those when you can't reverse the migration you can raise +IrreversibleMigration+ from your +down+ method. If someone tries to revert your migration an error message will be displayed saying that it can't be done.
h3. Running Migrations
@@ -449,7 +464,7 @@ For example, this migration
<ruby>
class CreateProducts < ActiveRecord::Migration
- def self.up
+ def change
suppress_messages do
create_table :products do |t|
t.string :name
@@ -465,10 +480,6 @@ class CreateProducts < ActiveRecord::Migration
250
end
end
-
- def self.down
- drop_table :products
- end
end
</ruby>
@@ -499,11 +510,7 @@ class AddPartNumberToProducts < ActiveRecord::Migration
class Product < ActiveRecord::Base
end
- def self.up
- ...
- end
-
- def self.down
+ def change
...
end
end
@@ -519,15 +526,11 @@ class AddPartNumberToProducts < ActiveRecord::Migration
class Product < ActiveRecord::Base
end
- def self.up
+ def change
add_column :product, :part_number, :string
Product.reset_column_information
...
end
-
- def self.down
- ...
- end
end
</ruby>
@@ -590,5 +593,6 @@ Although Active Record does not provide any tools for working directly with such
h3. Changelog
+* April 26, 2011: change generated +up+ and +down+ methods to +change+ method, and describe detail about +change+ method by "Prem Sichanugrist":http://sikachu.com
* July 15, 2010: minor typos corrected by "Jaime Iniesta":http://jaimeiniesta.com
* September 14, 2008: initial version by "Frederick Cheung":credits.html#fcheung
diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile
index 43c08165dc..99fdcee68a 100644
--- a/railties/guides/source/routing.textile
+++ b/railties/guides/source/routing.textile
@@ -391,7 +391,7 @@ NOTE: You can't use +namespace+ or +:module+ with a +:controller+ path segment.
match ':controller(/:action(/:id))', :controller => /admin\/[^\/]+/
</ruby>
-TIP: By default dynamic segments don't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment add a constraint which overrides this - for example +:id => /[^\/]<plus>/+ allows anything except a slash.
+TIP: By default dynamic segments don't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment add a constraint which overrides this - for example +:id+ => /[^\/]+/ allows anything except a slash.
h4. Static Segments
@@ -660,7 +660,7 @@ end
NOTE: Of course, you can use the more advanced constraints available in non-resourceful routes in this context.
-TIP: By default the +:id+ parameter doesn't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within an +:id+ add a constraint which overrides this - for example +:id => /[^\/]+/+ allows anything except a slash.
+TIP: By default the +:id+ parameter doesn't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within an +:id+ add a constraint which overrides this - for example +:id+ => /[^\/]+/ allows anything except a slash.
h4. Overriding the Named Helpers