Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Getting Started edit + 2.3 content

  • Loading branch information...
commit 6a6c8b77593cfd508874af6c4902455766d7e3cb 1 parent 3c04448
Mike Gunderloy ffmike authored
154 railties/doc/guides/source/getting_started_with_rails.txt
View
@@ -8,6 +8,8 @@ This guide covers getting up and running with Ruby on Rails. After reading it,
* The basic principles of MVC (Model, View Controller) and RESTful design
* How to quickly generate the starting pieces of a Rails application.
+NOTE: This Guide is based on Rails 2.3. Some of the code shown here will not work in older versions of Rails.
+
== This Guide Assumes
This guide is designed for beginners who want to get started with a Rails application from scratch. It does not assume that you have any prior experience with Rails. However, to get the most out of it, you need to have some prerequisites installed:
@@ -16,7 +18,7 @@ This guide is designed for beginners who want to get started with a Rails applic
* The link:http://rubyforge.org/frs/?group_id=126[RubyGems] packaging system
* A working installation of link:http://www.sqlite.org/[SQLite] (preferred), link:http://www.mysql.com/[MySQL], or link:http://www.postgresql.org/[PostgreSQL]
-It is highly recommended that you *familiarize yourself with Ruby before diving into Rails*. You will find it much easier to follow what's going on with a Rails application if you understand basic Ruby syntax. Rails isn't going to magically revolutionize the way you write web applications if you have no experience with the language it uses. There are some good free resources on the net for learning Ruby, including:
+It is highly recommended that you *familiarize yourself with Ruby before diving into Rails*. You will find it much easier to follow what's going on with a Rails application if you understand basic Ruby syntax. Rails isn't going to magically revolutionize the way you write web applications if you have no experience with the language it uses. There are some good free resources on the internet for learning Ruby, including:
* link:http://www.humblelittlerubybook.com/[Mr. Neigborly’s Humble Little Ruby Book]
* link:http://www.rubycentral.com/book/[Programming Ruby]
@@ -26,7 +28,7 @@ It is highly recommended that you *familiarize yourself with Ruby before diving
Rails is a web development framework written in the Ruby language. It is designed to make programming web applications easier by making several assumptions about what every developer needs to get started. It allows you to write less code while accomplishing more than many other languages and frameworks. Longtime Rails developers also report that it makes web application development more fun.
-Rails is _opinionated software_. That is, it assumes that there is a best way to do things, and it's designed to encourage that best way - and in some cases discourage alternatives. If you learn "The Rails Way" you'll probably discover a tremendous increase in productivity. If you persist in bringing old habits from other languages to your Rails development, and trying to use patterns you learned elsewhere, you may have a less happy experience.
+Rails is _opinionated software_. That is, it assumes that there is a best way to do things, and it's designed to encourage that best way - and in some cases to discourage alternatives. If you learn "The Rails Way" you'll probably discover a tremendous increase in productivity. If you persist in bringing old habits from other languages to your Rails development, and trying to use patterns you learned elsewhere, you may have a less happy experience.
The Rails philosophy includes several guiding principles:
@@ -105,7 +107,7 @@ For example, to a Rails application a request such as this:
+DELETE /photos/17+
-would be understood to refer to a photo resource with the ID of 17, and to indicate a desired action - deleting that resource. REST is a natural style for the architecture of web applications, and Rails makes it even more natural by using conventions to shield you from some of the RESTful complexities.
+would be understood to refer to a photo resource with the ID of 17, and to indicate a desired action - deleting that resource. REST is a natural style for the architecture of web applications, and Rails makes it even more natural by using conventions to shield you from some of the RESTful complexities and browser quirks.
If you’d like more details on REST as an architectural style, these resources are more approachable than Fielding’s thesis:
@@ -154,6 +156,8 @@ And if you're using PostgreSQL for data storage, run this command:
$ rails blog -d postgresql
-------------------------------------------------------
+TIP: You can see all of the switches that the Rails application builder accepts by running +rails -h+.
+
After you create the blog application, switch to its folder to continue work directly in that application:
[source, shell]
@@ -201,13 +205,12 @@ Here's the section of the default configuration file with connection information
development:
adapter: sqlite3
database: db/development.sqlite3
+ pool: 5
timeout: 5000
-------------------------------------------------------
If you don't have any database set up, SQLite is the easiest to get installed. If you're on OS X 10.5 or greater on a Mac, you already have it. Otherwise, you can install it using RubyGems:
-If you're not running OS X 10.5 or greater, you'll need to install the SQLite gem. Similar to installing Rails you just need to run:
-
[source, shell]
-------------------------------------------------------
$ gem install sqlite3-ruby
@@ -223,6 +226,7 @@ development:
adapter: mysql
encoding: utf8
database: blog_development
+ pool: 5
username: root
password:
socket: /tmp/mysql.sock
@@ -239,6 +243,7 @@ development:
adapter: postgresql
encoding: unicode
database: blog_development
+ pool: 5
username: blog
password:
-------------------------------------------------------
@@ -254,6 +259,8 @@ Now that you have your database configured, it's time to have Rails create an em
$ rake db:create
-------------------------------------------------------
+NOTE: Rake is a general-purpose command-runner that Rails uses for many things. You can see the list of available rake commands in your application by running +rake -T+.
+
== Hello, Rails!
One of the traditional places to start with a new language is by getting some text up on screen quickly. To do that in Rails, you need to create at minimum a controller and a view. Fortunately, you can do that in a single command. Enter this command in your terminal:
@@ -281,13 +288,13 @@ You actually have a functional Rails application already - after running only tw
$ script/server
-------------------------------------------------------
-This will fire up the lightweight Webrick web server by default. To see your application in action, open a browser window and navigate to +http://localhost:3000+. You should see Rails' default information page:
+This will fire up an instance of the Mongrel web server by default (Rails can also use several other web servers). To see your application in action, open a browser window and navigate to +http://localhost:3000+. You should see Rails' default information page:
image:images/rails_welcome.png[Welcome Aboard screenshot]
TIP: To stop the web server, hit Ctrl+C in the terminal window where it's running. In development mode, Rails does not generally require you to stop the server; changes you make in files will be automatically picked up by the server.
-The "Welcome Aboard" page is the smoke test for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. To view the page you just created, navigate to +http://localhost:3000/home/index+.
+The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. To view the page you just created, navigate to +http://localhost:3000/home/index+.
=== Setting the Application Home Page
@@ -336,13 +343,13 @@ $ script/generate scaffold Post name:string title:string content:text
NOTE: While scaffolding will get you up and running quickly, the "one size fits all" code that it generates is unlikely to be a perfect fit for your application. In most cases, you'll need to customize the generated code. Many experienced Rails developers avoid scaffolding entirely, preferring to write all or most of their source code from scratch.
-The scaffold generator will build 13 files in your application, along with some folders, and edit one more. Here's a quick overview of what it creates:
+The scaffold generator will build 14 files in your application, along with some folders, and edit one more. Here's a quick overview of what it creates:
[options="header"]
|==========================================================================================================
|File |Purpose
|app/models/post.rb |The Post model
-|db/migrate/20081013124235_create_posts.rb |Migration to create the posts table in your database (your name will include a different timestamp)
+|db/migrate/20090113124235_create_posts.rb |Migration to create the posts table in your database (your name will include a different timestamp)
|app/views/posts/index.html.erb |A view to display an index of all posts
|app/views/posts/show.html.erb |A view to display a single post
|app/views/posts/new.html.erb |A view to create a new post
@@ -355,13 +362,14 @@ The scaffold generator will build 13 files in your application, along with some
|config/routes.rb |Edited to include routing information for posts
|test/fixtures/posts.yml |Dummy posts for use in testing
|test/unit/post_test.rb |Unit testing harness for the posts model
+|test/unit/helpers/posts_helper_test.rb |Unit testing harness for the posts helper
|==========================================================================================================
=== Running a Migration
One of the products of the +script/generate scaffold+ command is a _database migration_. Migrations are Ruby classes that are designed to make it simple to create and modify database tables. Rails uses rake commands to run migrations, and it's possible to undo a migration after it's been applied to your database. Migration filenames include a timestamp to ensure that they're processed in the order that they were created.
-If you look in the +db/migrate/20081013124235_create_posts.rb+ file (remember, yours will have a slightly different name), here's what you'll find:
+If you look in the +db/migrate/20090113124235_create_posts.rb+ file (remember, yours will have a slightly different name), here's what you'll find:
[source, ruby]
-------------------------------------------------------
@@ -388,10 +396,11 @@ At this point, you can use a rake command to run the migration:
[source, shell]
-------------------------------------------------------
-$ rake db:create
$ rake db:migrate
-------------------------------------------------------
+Remember, you can't run migrations before running +rake db:create+ to create your database, as we covered earlier.
+
NOTE: Because you're working in the development environment by default, this command will apply to the database defined in the +development+ section of your +config/database.yml+ file.
=== Adding a Link
@@ -472,7 +481,7 @@ title: nil, content: "A new post", created_at: nil, updated_at: nil>,
This code shows creating a new +Post+ instance, attempting to save it and getting +false+ for a return value (indicating that the save failed), and inspecting the +errors+ of the post.
-TIP: Unlike the development web server, the console does not automatically load your code afresh for each line. If you make changes, type +reload!+ at the console prompt to load them.
+TIP: Unlike the development web server, the console does not automatically load your code afresh for each line. If you make changes to your models while the console is open, type +reload!+ at the console prompt to load them.
=== Listing All Posts
@@ -762,7 +771,7 @@ At this point, it’s worth looking at some of the tools that Rails provides to
=== Using Partials to Eliminate View Duplication
-As you saw earlier, the scaffold-generated views for the +new+ and +edit+ actions are largely identical. You can pull the shared code out into a +partial+ template. This requires editing the new and edit views, and adding a new template. The new +_form.html.erb+ template should be saved in the same +app/views/posts+ folder as the files from which it is being extracted:
+As you saw earlier, the scaffold-generated views for the +new+ and +edit+ actions are largely identical. You can pull the shared code out into a partial template. This requires editing the new and edit views, and adding a new template. The new +_form.html.erb+ template should be saved in the same +app/views/posts+ folder as the files from which it is being extracted. Note that the name of this file begins with an underscore; that's the Rails naming convention for partial templates.
+new.html.erb+:
@@ -876,7 +885,7 @@ end
Rails runs _before filters_ before any action in the controller. You can use the +:only+ clause to limit a before filter to only certain actions, or an +:except+ clause to specifically skip a before filter for certain actions. Rails also allows you to define _after filters_ that run after processing an action, as well as _around filters_ that surround the processing of actions. Filters can also be defined in external classes to make it easy to share them between controllers.
-For more information on filters, see the link:actioncontroller_basics.html[Action Controller Basics] guide.
+For more information on filters, see the link:../actioncontroller_basics.html[Action Controller Basics] guide.
== Adding a Second Model
@@ -894,7 +903,7 @@ $ script/generate model Comment commenter:string body:text post:references
This command will generate four files:
* +app/models/comment.rb+ - The model
-* +db/migrate/20081013214407_create_comments.rb - The migration
+* +db/migrate/20091013214407_create_comments.rb - The migration
* +test/unit/comment_test.rb+ and +test/fixtures/comments.yml+ - The test harness.
First, take a look at +comment.rb+:
@@ -936,7 +945,7 @@ The +t.references+ line sets up a foreign key column for the association between
$ rake db:migrate
-------------------------------------------------------
-Rails is smart enough to only execute the migrations that have not already been run against this particular database.
+Rails is smart enough to only execute the migrations that have not already been run against the current database.
=== Associating Models
@@ -971,13 +980,11 @@ TIP: For more information on Active Record associations, see the link:../associa
=== Adding a Route
-_Routes_ are entries in the +config/routes.rb+ file that tell Rails how to match incoming HTTP requests to controller actions. Open up that file and find the existing line referring to +posts+. Then edit it as follows:
+_Routes_ are entries in the +config/routes.rb+ file that tell Rails how to match incoming HTTP requests to controller actions. Open up that file and find the existing line referring to +posts+ (it will be right at the top of the file). Then edit it as follows:
[source, ruby]
-------------------------------------------------------
-map.resources :posts do |post|
- post.resources :comments
-end
+map.resources :posts, :has_many => :comments
-------------------------------------------------------
This creates +comments+ as a _nested resource_ within +posts+. This is another part of capturing the hierarchical relationship that exists between posts and comments.
@@ -1003,7 +1010,7 @@ This creates seven files:
* +app/views/comments/edit.html.erb+ - The view for the edit action
* +test/functional/comments_controller_test.rb+ - The functional tests for the controller
-The controller will be generated with empty methods for each action that you specified in the call to +script/generate controller+:
+The controller will be generated with empty methods and views for each action that you specified in the call to +script/generate controller+:
[source, ruby]
-------------------------------------------------------
@@ -1068,6 +1075,17 @@ class CommentsController < ApplicationController
end
end
+ def destroy
+ @post = Post.find(params[:post_id])
+ @comment = Comment.find(params[:id])
+ @comment.destroy
+
+ respond_to do |format|
+ format.html { redirect_to post_comments_path(@post) }
+ format.xml { head :ok }
+ end
+ end
+
end
-------------------------------------------------------
@@ -1086,7 +1104,7 @@ This creates a new +Comment+ object _and_ sets up the +post_id+ field to have th
Because you skipped scaffolding, you'll need to build views for comments "by hand." Invoking +script/generate controller+ will give you skeleton views, but they'll be devoid of actual content. Here's a first pass at fleshing out the comment views.
-The +index.html.erb+ view:
+The +views/comments/index.html.erb+ view:
[source, ruby]
-------------------------------------------------------
@@ -1115,7 +1133,7 @@ The +index.html.erb+ view:
<%= link_to 'Back to Post', @post %>
-------------------------------------------------------
-The +new.html.erb+ view:
+The +views/comments/new.html.erb+ view:
[source, ruby]
-------------------------------------------------------
@@ -1140,7 +1158,7 @@ The +new.html.erb+ view:
<%= link_to 'Back', post_comments_path(@post) %>
-------------------------------------------------------
-The +show.html.erb+ view:
+The +views/comments/show.html.erb+ view:
[source, ruby]
-------------------------------------------------------
@@ -1160,7 +1178,7 @@ The +show.html.erb+ view:
<%= link_to 'Back', post_comments_path(@post) %>
-------------------------------------------------------
-The +edit.html.erb+ view:
+The +views/comments/edit.html.erb+ view:
[source, ruby]
-------------------------------------------------------
@@ -1186,11 +1204,11 @@ The +edit.html.erb+ view:
<%= link_to 'Back', post_comments_path(@post) %>
-------------------------------------------------------
-Again, the added complexity here (compared to the views you saw for managing comments) comes from the necessity of juggling a post and its comments at the same time.
+Again, the added complexity here (compared to the views you saw for managing posts) comes from the necessity of juggling a post and its comments at the same time.
=== Hooking Comments to Posts
-As a final step, I'll modify the +show.html.erb+ view for a post to show the comments on that post, and to allow managing those comments:
+As a next step, I'll modify the +views/posts/show.html.erb+ view to show the comments on that post, and to allow managing those comments:
[source, ruby]
-------------------------------------------------------
@@ -1222,13 +1240,90 @@ As a final step, I'll modify the +show.html.erb+ view for a post to show the com
</p>
<% end %>
-<%= link_to 'Edit', edit_post_path(@post) %> |
-<%= link_to 'Back', posts_path %>
+<%= link_to 'Edit Post', edit_post_path(@post) %> |
+<%= link_to 'Back to Posts', posts_path %> |
<%= link_to 'Manage Comments', post_comments_path(@post) %>
-------------------------------------------------------
Note that each post has its own individual comments collection, accessible as +@post.comments+. That's a consequence of the declarative associations in the models. Path helpers such as +post_comments_path+ come from the nested route declaration in +config/routes.rb+.
+== Building a Multi-Model Form
+
+Comments and posts are edited on two separate forms - which makes sense, given the flow of this mini-application. But what if you want to edit more than one thing on a single form? Rails 2.3 offers new support for nested forms. Let's add support for giving each post multiple tags, right in the form where you create the post. First, create a new model to hold the tags:
+
+[source, shell]
+-------------------------------------------------------
+$ script/generate model tag name:string post:references
+-------------------------------------------------------
+
+Run the migration to create the database table:
+
+[source, shell]
+-------------------------------------------------------
+$ rake db:migrate
+-------------------------------------------------------
+
+Next, edit the +post.rb+ file to create the other side of the association, and to tell Rails that you intend to edit tags via posts:
+
+[source, ruby]
+-------------------------------------------------------
+class Post < ActiveRecord::Base
+ validates_presence_of :name, :title
+ validates_length_of :title, :minimum => 5
+ has_many :comments
+ has_many :tags
+
+ accepts_nested_attributes_for :tags, :allow_destroy => :true ,
+ :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
+end
+-------------------------------------------------------
+
+The +:allow_destroy+ option on the nested attribute declaration tells Rails to display a "remove" checkbox on the view that you'll build shortly. The +:reject_if+ option prevents saving new tags that do not have any attributes filled in.
+
+You'll also need to modify +views/posts/_form.html.erb+ to include the tags:
+
+[source, ruby]
+-------------------------------------------------------
+<% @post.tags.build if @post.tags.empty? %>
+<% form_for(@post) do |post_form| %>
+ <%= post_form.error_messages %>
+
+ <p>
+ <%= post_form.label :name %><br />
+ <%= post_form.text_field :name %>
+ </p>
+ <p>
+ <%= post_form.label :title, "title" %><br />
+ <%= post_form.text_field :title %>
+ </p>
+ <p>
+ <%= post_form.label :content %><br />
+ <%= post_form.text_area :content %>
+ </p>
+ <h2>Tags</h2>
+ <% post_form.fields_for :tags do |tag_form| %>
+ <p>
+ <%= tag_form.label :name, 'Tag:' %>
+ <%= tag_form.text_field :name %>
+ </p>
+ <% unless tag_form.object.nil? || tag_form.object.new_record? %>
+ <p>
+ <%= tag_form.label :_delete, 'Remove:' %>
+ <%= tag_form.check_box :_delete %>
+ </p>
+ <% end %>
+ <% end %>
+
+ <p>
+ <%= post_form.submit "Save" %>
+ </p>
+<% end %>
+-------------------------------------------------------
+
+With these changes in place, you'll find that you can edit a post and its tags directly on the same view.
+
+NOTE: You may want to use javascript to dynamically add additional tags on a single form. For an example of this and other advanced techniques, see the link:http://github.com/alloy/complex-form-examples/tree/nested_attributes[nested model sample application].
+
== What's Next?
Now that you've seen your first Rails application, you should feel free to update it and experiment on your own. But you don't have to do everything without help. As you need assistance getting up and running with Rails, feel free to consult these support resources:
@@ -1247,6 +1342,7 @@ Rails also comes with built-in help that you can generate using the rake command
http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/2[Lighthouse ticket]
+*
* November 3, 2008: Formatting patch from Dave Rothlisberger
* November 1, 2008: First approved version by link:../authors.html#mgunderloy[Mike Gunderloy]
* October 16, 2008: Revised based on feedback from Pratik Naik by link:../authors.html#mgunderloy[Mike Gunderloy] (not yet approved for publication)
BIN  railties/doc/guides/source/images/posts_index.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  railties/doc/guides/source/images/rails_welcome.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Please sign in to comment.
Something went wrong with that request. Please try again.