Skip to content
This repository
Browse code

Getting Started edit + 2.3 content

  • Loading branch information...
commit 6a6c8b77593cfd508874af6c4902455766d7e3cb 1 parent 3c04448
Mike Gunderloy authored February 01, 2009
154  railties/doc/guides/source/getting_started_with_rails.txt
@@ -8,6 +8,8 @@ This guide covers getting up and running with Ruby on Rails.  After reading it,
8 8
 * The basic principles of MVC (Model, View Controller) and RESTful design
9 9
 * How to quickly generate the starting pieces of a Rails application.
10 10
 
  11
+NOTE: This Guide is based on Rails 2.3. Some of the code shown here will not work in older versions of Rails.
  12
+
11 13
 == This Guide Assumes
12 14
 
13 15
 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
16 18
 * The link:http://rubyforge.org/frs/?group_id=126[RubyGems] packaging system
17 19
 * A working installation of link:http://www.sqlite.org/[SQLite] (preferred), link:http://www.mysql.com/[MySQL], or link:http://www.postgresql.org/[PostgreSQL]
18 20
 
19  
-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:
  21
+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:
20 22
 
21 23
 * link:http://www.humblelittlerubybook.com/[Mr. Neigborly’s Humble Little Ruby Book]
22 24
 * link:http://www.rubycentral.com/book/[Programming Ruby]
@@ -26,7 +28,7 @@ It is highly recommended that you *familiarize yourself with Ruby before diving
26 28
 
27 29
 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.
28 30
 
29  
-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.
  31
+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.
30 32
 
31 33
 The Rails philosophy includes several guiding principles:
32 34
 
@@ -105,7 +107,7 @@ For example, to a Rails application a request such as this:
105 107
 
106 108
 +DELETE /photos/17+
107 109
 
108  
-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.
  110
+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.
109 111
 
110 112
 If you’d like more details on REST as an architectural style, these resources are more approachable than Fielding’s thesis:
111 113
 
@@ -154,6 +156,8 @@ And if you're using PostgreSQL for data storage, run this command:
154 156
 $ rails blog -d postgresql
155 157
 -------------------------------------------------------
156 158
 
  159
+TIP: You can see all of the switches that the Rails application builder accepts by running +rails -h+.
  160
+
157 161
 After you create the blog application, switch to its folder to continue work directly in that application:
158 162
 
159 163
 [source, shell]
@@ -201,13 +205,12 @@ Here's the section of the default configuration file with connection information
201 205
 development:
202 206
   adapter: sqlite3
203 207
   database: db/development.sqlite3
  208
+  pool: 5
204 209
   timeout: 5000
205 210
 -------------------------------------------------------
206 211
 
207 212
 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:
208 213
 
209  
-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:
210  
-
211 214
 [source, shell]
212 215
 -------------------------------------------------------
213 216
 $ gem install sqlite3-ruby
@@ -223,6 +226,7 @@ development:
223 226
   adapter: mysql
224 227
   encoding: utf8
225 228
   database: blog_development
  229
+  pool: 5
226 230
   username: root
227 231
   password:
228 232
   socket: /tmp/mysql.sock
@@ -239,6 +243,7 @@ development:
239 243
   adapter: postgresql
240 244
   encoding: unicode
241 245
   database: blog_development
  246
+  pool: 5
242 247
   username: blog
243 248
   password:
244 249
 -------------------------------------------------------
@@ -254,6 +259,8 @@ Now that you have your database configured, it's time to have Rails create an em
254 259
 $ rake db:create
255 260
 -------------------------------------------------------
256 261
 
  262
+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+. 
  263
+
257 264
 == Hello, Rails!
258 265
 
259 266
 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
281 288
 $ script/server
282 289
 -------------------------------------------------------
283 290
 
284  
-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:
  291
+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:
285 292
 
286 293
 image:images/rails_welcome.png[Welcome Aboard screenshot]
287 294
 
288 295
 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.
289 296
 
290  
-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+.
  297
+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+.
291 298
 
292 299
 === Setting the Application Home Page
293 300
 
@@ -336,13 +343,13 @@ $ script/generate scaffold Post name:string title:string content:text
336 343
 
337 344
 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.
338 345
 
339  
-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:
  346
+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:
340 347
 
341 348
 [options="header"]
342 349
 |==========================================================================================================
343 350
 |File                                          |Purpose
344 351
 |app/models/post.rb                            |The Post model
345  
-|db/migrate/20081013124235_create_posts.rb     |Migration to create the posts table in your database (your name will include a different timestamp)
  352
+|db/migrate/20090113124235_create_posts.rb     |Migration to create the posts table in your database (your name will include a different timestamp)
346 353
 |app/views/posts/index.html.erb                |A view to display an index of all posts 
347 354
 |app/views/posts/show.html.erb                 |A view to display a single post
348 355
 |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
355 362
 |config/routes.rb                              |Edited to include routing information for posts
356 363
 |test/fixtures/posts.yml                       |Dummy posts for use in testing
357 364
 |test/unit/post_test.rb                        |Unit testing harness for the posts model
  365
+|test/unit/helpers/posts_helper_test.rb        |Unit testing harness for the posts helper
358 366
 |==========================================================================================================
359 367
 
360 368
 === Running a Migration
361 369
 
362 370
 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.
363 371
 
364  
-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:
  372
+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:
365 373
 
366 374
 [source, ruby]
367 375
 -------------------------------------------------------
@@ -388,10 +396,11 @@ At this point, you can use a rake command to run the migration:
388 396
 
389 397
 [source, shell]
390 398
 -------------------------------------------------------
391  
-$ rake db:create
392 399
 $ rake db:migrate
393 400
 -------------------------------------------------------
394 401
 
  402
+Remember, you can't run migrations before running +rake db:create+ to create your database, as we covered earlier.
  403
+
395 404
 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.
396 405
 
397 406
 === Adding a Link
@@ -472,7 +481,7 @@ title: nil, content: "A new post", created_at: nil, updated_at: nil>,
472 481
 
473 482
 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.
474 483
 
475  
-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.
  484
+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.
476 485
 
477 486
 === Listing All Posts
478 487
 
@@ -762,7 +771,7 @@ At this point, it’s worth looking at some of the tools that Rails provides to
762 771
 
763 772
 === Using Partials to Eliminate View Duplication
764 773
 
765  
-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:
  774
+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.
766 775
 
767 776
 +new.html.erb+:
768 777
 
@@ -876,7 +885,7 @@ end
876 885
 
877 886
 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.
878 887
 
879  
-For more information on filters, see the link:actioncontroller_basics.html[Action Controller Basics] guide.
  888
+For more information on filters, see the link:../actioncontroller_basics.html[Action Controller Basics] guide.
880 889
 
881 890
 == Adding a Second Model
882 891
 
@@ -894,7 +903,7 @@ $ script/generate model Comment commenter:string body:text post:references
894 903
 This command will generate four files:
895 904
 
896 905
 * +app/models/comment.rb+ - The model
897  
-* +db/migrate/20081013214407_create_comments.rb - The migration
  906
+* +db/migrate/20091013214407_create_comments.rb - The migration
898 907
 * +test/unit/comment_test.rb+ and +test/fixtures/comments.yml+ - The test harness.
899 908
 
900 909
 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
936 945
 $ rake db:migrate
937 946
 -------------------------------------------------------
938 947
 
939  
-Rails is smart enough to only execute the migrations that have not already been run against this particular database.
  948
+Rails is smart enough to only execute the migrations that have not already been run against the current database.
940 949
 
941 950
 === Associating Models
942 951
 
@@ -971,13 +980,11 @@ TIP: For more information on Active Record associations, see the link:../associa
971 980
 
972 981
 === Adding a Route
973 982
 
974  
-_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:
  983
+_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:
975 984
 
976 985
 [source, ruby]
977 986
 -------------------------------------------------------
978  
-map.resources :posts do |post|
979  
-  post.resources :comments
980  
-end
  987
+map.resources :posts, :has_many => :comments
981 988
 -------------------------------------------------------
982 989
 
983 990
 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:
1003 1010
 * +app/views/comments/edit.html.erb+ - The view for the edit action
1004 1011
 * +test/functional/comments_controller_test.rb+ - The functional tests for the controller
1005 1012
 
1006  
-The controller will be generated with empty methods for each action that you specified in the call to +script/generate controller+:
  1013
+The controller will be generated with empty methods and views for each action that you specified in the call to +script/generate controller+:
1007 1014
 
1008 1015
 [source, ruby]
1009 1016
 -------------------------------------------------------
@@ -1068,6 +1075,17 @@ class CommentsController < ApplicationController
1068 1075
     end
1069 1076
   end
1070 1077
   
  1078
+  def destroy
  1079
+    @post = Post.find(params[:post_id])
  1080
+    @comment = Comment.find(params[:id])
  1081
+    @comment.destroy
  1082
+
  1083
+    respond_to do |format|
  1084
+      format.html { redirect_to post_comments_path(@post) }
  1085
+      format.xml  { head :ok }
  1086
+    end
  1087
+  end
  1088
+
1071 1089
 end
1072 1090
 -------------------------------------------------------
1073 1091
 
@@ -1086,7 +1104,7 @@ This creates a new +Comment+ object _and_ sets up the +post_id+ field to have th
1086 1104
 
1087 1105
 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.
1088 1106
 
1089  
-The +index.html.erb+ view:
  1107
+The +views/comments/index.html.erb+ view:
1090 1108
 
1091 1109
 [source, ruby]
1092 1110
 -------------------------------------------------------
@@ -1115,7 +1133,7 @@ The +index.html.erb+ view:
1115 1133
 <%= link_to 'Back to Post', @post %>
1116 1134
 -------------------------------------------------------
1117 1135
 
1118  
-The +new.html.erb+ view:
  1136
+The +views/comments/new.html.erb+ view:
1119 1137
 
1120 1138
 [source, ruby]
1121 1139
 -------------------------------------------------------
@@ -1140,7 +1158,7 @@ The +new.html.erb+ view:
1140 1158
 <%= link_to 'Back', post_comments_path(@post) %>
1141 1159
 -------------------------------------------------------
1142 1160
 
1143  
-The +show.html.erb+ view:
  1161
+The +views/comments/show.html.erb+ view:
1144 1162
 
1145 1163
 [source, ruby]
1146 1164
 -------------------------------------------------------
@@ -1160,7 +1178,7 @@ The +show.html.erb+ view:
1160 1178
 <%= link_to 'Back', post_comments_path(@post) %>
1161 1179
 -------------------------------------------------------
1162 1180
 
1163  
-The +edit.html.erb+ view:
  1181
+The +views/comments/edit.html.erb+ view:
1164 1182
 
1165 1183
 [source, ruby]
1166 1184
 -------------------------------------------------------
@@ -1186,11 +1204,11 @@ The +edit.html.erb+ view:
1186 1204
 <%= link_to 'Back', post_comments_path(@post) %>
1187 1205
 -------------------------------------------------------
1188 1206
 
1189  
-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.
  1207
+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.
1190 1208
 
1191 1209
 === Hooking Comments to Posts
1192 1210
 
1193  
-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:
  1211
+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:
1194 1212
 
1195 1213
 [source, ruby]
1196 1214
 -------------------------------------------------------
@@ -1222,13 +1240,90 @@ As a final step, I'll modify the +show.html.erb+ view for a post to show the com
1222 1240
 	</p>
1223 1241
 <% end %>
1224 1242
 
1225  
-<%= link_to 'Edit', edit_post_path(@post) %> |
1226  
-<%= link_to 'Back', posts_path %>
  1243
+<%= link_to 'Edit Post', edit_post_path(@post) %> |
  1244
+<%= link_to 'Back to Posts', posts_path %> |
1227 1245
 <%= link_to 'Manage Comments', post_comments_path(@post) %>
1228 1246
 -------------------------------------------------------
1229 1247
 
1230 1248
 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+.
1231 1249
 
  1250
+== Building a Multi-Model Form
  1251
+
  1252
+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:
  1253
+
  1254
+[source, shell]
  1255
+-------------------------------------------------------
  1256
+$ script/generate model tag name:string post:references
  1257
+-------------------------------------------------------
  1258
+
  1259
+Run the migration to create the database table:
  1260
+
  1261
+[source, shell]
  1262
+-------------------------------------------------------
  1263
+$ rake db:migrate
  1264
+-------------------------------------------------------
  1265
+
  1266
+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:
  1267
+
  1268
+[source, ruby]
  1269
+-------------------------------------------------------
  1270
+class Post < ActiveRecord::Base
  1271
+  validates_presence_of :name, :title
  1272
+  validates_length_of :title, :minimum => 5
  1273
+  has_many :comments
  1274
+  has_many :tags
  1275
+  
  1276
+  accepts_nested_attributes_for :tags, :allow_destroy => :true	,
  1277
+  	:reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
  1278
+end
  1279
+-------------------------------------------------------
  1280
+
  1281
+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.
  1282
+
  1283
+You'll also need to modify +views/posts/_form.html.erb+ to include the tags:
  1284
+
  1285
+[source, ruby]
  1286
+-------------------------------------------------------
  1287
+<% @post.tags.build if @post.tags.empty? %>
  1288
+<% form_for(@post) do |post_form| %>
  1289
+  <%= post_form.error_messages %>
  1290
+
  1291
+  <p>
  1292
+    <%= post_form.label :name %><br />
  1293
+    <%= post_form.text_field :name %>
  1294
+  </p>
  1295
+  <p>
  1296
+    <%= post_form.label :title, "title" %><br />
  1297
+    <%= post_form.text_field :title %>
  1298
+  </p>
  1299
+  <p>
  1300
+    <%= post_form.label :content %><br />
  1301
+    <%= post_form.text_area :content %>
  1302
+  </p>
  1303
+  <h2>Tags</h2>
  1304
+  <% post_form.fields_for :tags do |tag_form| %>
  1305
+    <p>
  1306
+      <%= tag_form.label :name, 'Tag:' %>
  1307
+      <%= tag_form.text_field :name %>
  1308
+    </p>
  1309
+    <% unless tag_form.object.nil? || tag_form.object.new_record? %>
  1310
+      <p>
  1311
+        <%= tag_form.label :_delete, 'Remove:' %>
  1312
+        <%= tag_form.check_box :_delete %>
  1313
+      </p>
  1314
+    <% end %>
  1315
+  <% end %>
  1316
+
  1317
+  <p>
  1318
+    <%= post_form.submit "Save" %>
  1319
+  </p>
  1320
+<% end %>
  1321
+-------------------------------------------------------
  1322
+
  1323
+With these changes in place, you'll find that you can edit a post and its tags directly on the same view.
  1324
+
  1325
+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].
  1326
+
1232 1327
 == What's Next?
1233 1328
 
1234 1329
 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
1247 1342
 
1248 1343
 http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/2[Lighthouse ticket]
1249 1344
 
  1345
+* 
1250 1346
 * November 3, 2008: Formatting patch from Dave Rothlisberger
1251 1347
 * November 1, 2008: First approved version by link:../authors.html#mgunderloy[Mike Gunderloy]
1252 1348
 * 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
BIN  railties/doc/guides/source/images/rails_welcome.png

0 notes on commit 6a6c8b7

Please sign in to comment.
Something went wrong with that request. Please try again.