diff options
Diffstat (limited to 'railties/guides')
9 files changed, 142 insertions, 152 deletions
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://<your user name>@github.com/<your user name>/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/<your user name>/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 |