railties 3.0.0.beta → 3.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +15 -1
- data/README +9 -9
- data/bin/rails +28 -9
- data/guides/images/challenge.png +0 -0
- data/guides/images/edge_badge.png +0 -0
- data/guides/images/posts_index.png +0 -0
- data/guides/images/rails_welcome.png +0 -0
- data/guides/rails_guides.rb +9 -22
- data/guides/rails_guides/generator.rb +79 -50
- data/guides/rails_guides/textile_extensions.rb +3 -3
- data/guides/source/2_2_release_notes.textile +1 -1
- data/guides/source/2_3_release_notes.textile +1 -1
- data/guides/source/3_0_release_notes.textile +46 -38
- data/guides/source/action_controller_overview.textile +2 -2
- data/guides/source/action_mailer_basics.textile +4 -4
- data/guides/source/action_view_overview.textile +2 -2
- data/guides/source/active_record_querying.textile +73 -95
- data/guides/source/active_support_core_extensions.textile +993 -85
- data/guides/source/activerecord_validations_callbacks.textile +3 -3
- data/guides/source/caching_with_rails.textile +1 -1
- data/guides/source/command_line.textile +90 -88
- data/guides/source/configuring.textile +10 -10
- data/guides/source/contribute.textile +2 -2
- data/guides/source/contributing_to_rails.textile +14 -7
- data/guides/source/credits.textile.erb +8 -0
- data/guides/source/debugging_rails_applications.textile +6 -6
- data/guides/source/form_helpers.textile +1 -1
- data/guides/source/generators.textile +14 -14
- data/guides/source/getting_started.textile +634 -500
- data/guides/source/index.textile.erb +16 -1
- data/guides/source/layout.html.erb +7 -1
- data/guides/source/layouts_and_rendering.textile +299 -71
- data/guides/source/migrations.textile +5 -5
- data/guides/source/performance_testing.textile +8 -8
- data/guides/source/plugins.textile +26 -24
- data/guides/source/rails_on_rack.textile +5 -5
- data/guides/source/routing.textile +119 -117
- data/guides/source/security.textile +1 -1
- data/guides/source/testing.textile +4 -4
- data/lib/rails.rb +4 -1
- data/lib/rails/application.rb +44 -7
- data/lib/rails/application/bootstrap.rb +2 -14
- data/lib/rails/application/configuration.rb +69 -5
- data/lib/rails/application/finisher.rb +2 -3
- data/lib/rails/application/metal_loader.rb +1 -1
- data/lib/rails/application/routes_reloader.rb +1 -1
- data/lib/rails/backtrace_cleaner.rb +0 -11
- data/lib/rails/commands.rb +7 -6
- data/lib/rails/commands/application.rb +1 -1
- data/lib/rails/commands/console.rb +1 -1
- data/lib/rails/commands/dbconsole.rb +12 -0
- data/lib/rails/commands/destroy.rb +2 -2
- data/lib/rails/commands/generate.rb +2 -2
- data/lib/rails/commands/performance/benchmarker.rb +2 -2
- data/lib/rails/commands/performance/profiler.rb +2 -2
- data/lib/rails/commands/plugin.rb +6 -6
- data/lib/rails/commands/runner.rb +2 -0
- data/lib/rails/commands/server.rb +23 -8
- data/lib/rails/configuration.rb +2 -84
- data/lib/rails/console/app.rb +4 -3
- data/lib/rails/console/helpers.rb +3 -1
- data/lib/rails/engine.rb +107 -12
- data/lib/rails/engine/configuration.rb +8 -2
- data/lib/rails/generators.rb +22 -7
- data/lib/rails/generators/actions.rb +16 -6
- data/lib/rails/generators/base.rb +15 -8
- data/lib/rails/generators/erb.rb +21 -0
- data/lib/{generators → rails/generators}/erb/controller/controller_generator.rb +4 -5
- data/lib/{generators → rails/generators}/erb/controller/templates/view.html.erb +0 -0
- data/lib/rails/generators/erb/mailer/mailer_generator.rb +13 -0
- data/lib/{generators → rails/generators}/erb/mailer/templates/view.text.erb +0 -0
- data/lib/{generators → rails/generators}/erb/scaffold/scaffold_generator.rb +14 -26
- data/lib/{generators → rails/generators}/erb/scaffold/templates/_form.html.erb +1 -1
- data/lib/{generators → rails/generators}/erb/scaffold/templates/edit.html.erb +0 -0
- data/lib/{generators → rails/generators}/erb/scaffold/templates/index.html.erb +1 -1
- data/lib/{generators → rails/generators}/erb/scaffold/templates/layout.html.erb +1 -0
- data/lib/{generators → rails/generators}/erb/scaffold/templates/new.html.erb +0 -0
- data/lib/{generators → rails/generators}/erb/scaffold/templates/show.html.erb +0 -0
- data/lib/rails/generators/named_base.rb +4 -0
- data/lib/{generators → rails/generators}/rails/app/USAGE +0 -0
- data/lib/{generators → rails/generators}/rails/app/app_generator.rb +21 -7
- data/lib/rails/generators/rails/app/templates/Gemfile +34 -0
- data/lib/{generators → rails/generators}/rails/app/templates/README +9 -8
- data/lib/{generators → rails/generators}/rails/app/templates/Rakefile +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/app/controllers/application_controller.rb +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/app/helpers/application_helper.rb +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/app/models/.empty_directory +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/app/views/layouts/.empty_directory +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config.ru +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/application.rb +4 -3
- data/lib/rails/generators/rails/app/templates/config/boot.rb +14 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/databases/frontbase.yml +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/databases/ibm_db.yml +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/databases/mysql.yml +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/databases/oracle.yml +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/databases/postgresql.yml +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/databases/sqlite3.yml +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/environment.rb +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/environments/development.rb.tt +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/environments/production.rb.tt +9 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/environments/test.rb.tt +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/initializers/backtrace_silencers.rb +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt +1 -1
- data/lib/{generators → rails/generators}/rails/app/templates/config/initializers/inflections.rb +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/initializers/mime_types.rb +0 -0
- data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +10 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/locales/en.yml +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/config/routes.rb +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/db/seeds.rb +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/doc/README_FOR_APP +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/gitignore +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/public/404.html +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/public/422.html +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/public/500.html +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/public/favicon.ico +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/public/images/rails.png +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/public/index.html +17 -17
- data/lib/{generators → rails/generators}/rails/app/templates/public/javascripts/application.js +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/public/javascripts/controls.js +5 -3
- data/lib/{generators → rails/generators}/rails/app/templates/public/javascripts/dragdrop.js +7 -6
- data/lib/{generators → rails/generators}/rails/app/templates/public/javascripts/effects.js +8 -13
- data/lib/{generators → rails/generators}/rails/app/templates/public/javascripts/prototype.js +1573 -1019
- data/lib/{generators → rails/generators}/rails/app/templates/public/javascripts/rails.js +1 -2
- data/lib/{generators → rails/generators}/rails/app/templates/public/robots.txt +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/public/stylesheets/.empty_directory +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/script/rails +0 -1
- data/lib/{generators → rails/generators}/rails/app/templates/test/fixtures/.empty_directory +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/test/functional/.empty_directory +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/test/integration/.empty_directory +0 -0
- data/lib/{generators → rails/generators}/rails/app/templates/test/performance/browsing_test.rb +1 -1
- data/lib/{generators → rails/generators}/rails/app/templates/test/test_helper.rb +1 -1
- data/lib/{generators → rails/generators}/rails/app/templates/test/unit/.empty_directory +0 -0
- data/lib/{generators → rails/generators}/rails/controller/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/controller/controller_generator.rb +6 -0
- data/lib/{generators → rails/generators}/rails/controller/templates/controller.rb +0 -0
- data/lib/{generators → rails/generators}/rails/generator/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/generator/generator_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/generator/templates/%file_name%_generator.rb.tt +0 -0
- data/lib/{generators → rails/generators}/rails/generator/templates/USAGE.tt +1 -1
- data/lib/{generators → rails/generators}/rails/generator/templates/templates/.empty_directory +0 -0
- data/lib/{generators → rails/generators}/rails/helper/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/helper/helper_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/helper/templates/helper.rb +0 -0
- data/lib/{generators → rails/generators}/rails/integration_test/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/integration_test/integration_test_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/mailer/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/mailer/mailer_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/mailer/templates/mailer.rb +0 -0
- data/lib/{generators → rails/generators}/rails/metal/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/metal/metal_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/metal/templates/metal.rb +0 -0
- data/lib/{generators → rails/generators}/rails/migration/USAGE +2 -2
- data/lib/{generators → rails/generators}/rails/migration/migration_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/model/USAGE +2 -2
- data/lib/{generators → rails/generators}/rails/model/model_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/observer/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/observer/observer_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/performance_test/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/performance_test/performance_test_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/plugin/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/plugin/plugin_generator.rb +1 -1
- data/lib/{generators → rails/generators}/rails/plugin/templates/MIT-LICENSE.tt +0 -0
- data/lib/{generators → rails/generators}/rails/plugin/templates/README.tt +0 -0
- data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +23 -0
- data/lib/{generators → rails/generators}/rails/plugin/templates/init.rb +0 -0
- data/lib/{generators → rails/generators}/rails/plugin/templates/install.rb +0 -0
- data/lib/{generators → rails/generators}/rails/plugin/templates/lib/%file_name%.rb.tt +0 -0
- data/lib/{generators → rails/generators}/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt +0 -0
- data/lib/{generators → rails/generators}/rails/plugin/templates/uninstall.rb +0 -0
- data/lib/{generators → rails/generators}/rails/resource/USAGE +3 -3
- data/lib/{generators → rails/generators}/rails/resource/resource_generator.rb +3 -1
- data/lib/{generators → rails/generators}/rails/scaffold/USAGE +4 -4
- data/lib/{generators → rails/generators}/rails/scaffold/scaffold_generator.rb +1 -1
- data/lib/{generators → rails/generators}/rails/scaffold_controller/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/scaffold_controller/scaffold_controller_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/scaffold_controller/templates/controller.rb +2 -2
- data/lib/{generators → rails/generators}/rails/session_migration/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/session_migration/session_migration_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/stylesheets/USAGE +1 -1
- data/lib/{generators → rails/generators}/rails/stylesheets/stylesheets_generator.rb +0 -0
- data/lib/{generators → rails/generators}/rails/stylesheets/templates/scaffold.css +4 -0
- data/lib/{generators → rails/generators}/test_unit.rb +0 -0
- data/lib/{generators → rails/generators}/test_unit/controller/controller_generator.rb +2 -1
- data/lib/rails/generators/test_unit/controller/templates/functional_test.rb +18 -0
- data/lib/{generators → rails/generators}/test_unit/helper/helper_generator.rb +1 -1
- data/lib/{generators → rails/generators}/test_unit/helper/templates/helper_test.rb +0 -0
- data/lib/{generators → rails/generators}/test_unit/integration/integration_generator.rb +1 -1
- data/lib/{generators → rails/generators}/test_unit/integration/templates/integration_test.rb +0 -0
- data/lib/{generators → rails/generators}/test_unit/mailer/mailer_generator.rb +1 -8
- data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb +20 -0
- data/lib/{generators → rails/generators}/test_unit/model/model_generator.rb +1 -1
- data/lib/{generators → rails/generators}/test_unit/model/templates/fixtures.yml +0 -0
- data/lib/{generators → rails/generators}/test_unit/model/templates/unit_test.rb +0 -0
- data/lib/{generators → rails/generators}/test_unit/observer/observer_generator.rb +1 -1
- data/lib/{generators → rails/generators}/test_unit/observer/templates/unit_test.rb +0 -0
- data/lib/{generators → rails/generators}/test_unit/performance/performance_generator.rb +1 -1
- data/lib/{generators → rails/generators}/test_unit/performance/templates/performance_test.rb +0 -0
- data/lib/{generators → rails/generators}/test_unit/plugin/plugin_generator.rb +1 -1
- data/lib/{generators → rails/generators}/test_unit/plugin/templates/%file_name%_test.rb.tt +0 -0
- data/lib/{generators → rails/generators}/test_unit/plugin/templates/test_helper.rb +0 -0
- data/lib/{generators → rails/generators}/test_unit/scaffold/scaffold_generator.rb +1 -1
- data/lib/{generators → rails/generators}/test_unit/scaffold/templates/functional_test.rb +9 -5
- data/{builtin/rails_info → lib}/rails/info.rb +0 -0
- data/{builtin/rails_info → lib}/rails/info_controller.rb +0 -0
- data/{builtin/routes.rb → lib/rails/info_routes.rb} +2 -2
- data/lib/rails/{subscriber.rb → log_subscriber.rb} +27 -27
- data/lib/rails/{subscriber → log_subscriber}/test_helper.rb +15 -16
- data/lib/rails/plugin.rb +31 -8
- data/lib/rails/rack/debugger.rb +3 -1
- data/lib/rails/rack/logger.rb +4 -4
- data/lib/rails/railtie.rb +179 -16
- data/lib/rails/railtie/configuration.rb +56 -1
- data/lib/rails/tasks/documentation.rake +38 -20
- data/lib/rails/tasks/framework.rake +16 -9
- data/lib/rails/tasks/misc.rake +3 -5
- data/lib/rails/tasks/routes.rake +2 -2
- data/lib/rails/test_help.rb +21 -1
- data/lib/rails/test_unit/railtie.rb +1 -3
- data/lib/rails/version.rb +3 -2
- metadata +199 -171
- data/builtin/rails_info/rails/info_helper.rb +0 -2
- data/lib/generators/erb.rb +0 -8
- data/lib/generators/erb/mailer/mailer_generator.rb +0 -20
- data/lib/generators/rails/app/templates/Gemfile +0 -34
- data/lib/generators/rails/app/templates/config/boot.rb +0 -17
- data/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt +0 -15
- data/lib/generators/rails/model_subclass/model_subclass_generator.rb +0 -12
- data/lib/generators/rails/plugin/templates/Rakefile.tt +0 -10
- data/lib/generators/test_unit/controller/templates/functional_test.rb +0 -8
- data/lib/generators/test_unit/mailer/templates/fixture +0 -3
- data/lib/generators/test_unit/mailer/templates/functional_test.rb +0 -22
- data/lib/rails/railties_path.rb +0 -1
@@ -105,7 +105,7 @@ h4. Creating a Model
|
|
105
105
|
The model and scaffold generators will create migrations appropriate for adding a new model. This migration will already contain instructions for creating the relevant table. If you tell Rails what columns you want then statements for adding those will also be created. For example, running
|
106
106
|
|
107
107
|
<shell>
|
108
|
-
|
108
|
+
rails generate model Product name:string description:text
|
109
109
|
</shell>
|
110
110
|
|
111
111
|
will create a migration that looks like this
|
@@ -135,7 +135,7 @@ h4. Creating a Standalone Migration
|
|
135
135
|
If you are creating migrations for other purposes (for example to add a column to an existing table) then you can use the migration generator:
|
136
136
|
|
137
137
|
<shell>
|
138
|
-
|
138
|
+
rails generate migration AddPartNumberToProducts
|
139
139
|
</shell>
|
140
140
|
|
141
141
|
This will create an empty but appropriately named migration:
|
@@ -153,7 +153,7 @@ end
|
|
153
153
|
If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is followed by a list of column names and types then a migration containing the appropriate +add_column+ and +remove_column+ statements will be created.
|
154
154
|
|
155
155
|
<shell>
|
156
|
-
|
156
|
+
rails generate migration AddPartNumberToProducts part_number:string
|
157
157
|
</shell>
|
158
158
|
|
159
159
|
will generate
|
@@ -173,7 +173,7 @@ end
|
|
173
173
|
Similarly,
|
174
174
|
|
175
175
|
<shell>
|
176
|
-
|
176
|
+
rails generate migration RemovePartNumberFromProducts part_number:string
|
177
177
|
</shell>
|
178
178
|
|
179
179
|
generates
|
@@ -193,7 +193,7 @@ end
|
|
193
193
|
You are not limited to one magically generated column, for example
|
194
194
|
|
195
195
|
<shell>
|
196
|
-
|
196
|
+
rails generate migration AddDetailsToProducts part_number:string price:decimal
|
197
197
|
</shell>
|
198
198
|
|
199
199
|
generates
|
@@ -37,7 +37,7 @@ h4. Generating Performance Tests
|
|
37
37
|
Rails provides a generator called +performance_test+ for creating new performance tests:
|
38
38
|
|
39
39
|
<shell>
|
40
|
-
|
40
|
+
rails generate performance_test homepage
|
41
41
|
</shell>
|
42
42
|
|
43
43
|
This generates +homepage_test.rb+ in the +test/performance+ directory:
|
@@ -381,19 +381,19 @@ h4. +benchmarker+
|
|
381
381
|
Usage:
|
382
382
|
|
383
383
|
<shell>
|
384
|
-
$
|
384
|
+
$ rails benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ...
|
385
385
|
</shell>
|
386
386
|
|
387
387
|
Examples:
|
388
388
|
|
389
389
|
<shell>
|
390
|
-
$
|
390
|
+
$ rails benchmarker 10 'Item.all' 'CouchItem.all'
|
391
391
|
</shell>
|
392
392
|
|
393
393
|
If the +[times]+ argument is omitted, supplied methods are run just once:
|
394
394
|
|
395
395
|
<shell>
|
396
|
-
$
|
396
|
+
$ rails benchmarker 'Item.first' 'Item.last'
|
397
397
|
</shell>
|
398
398
|
|
399
399
|
h4. +profiler+
|
@@ -403,19 +403,19 @@ h4. +profiler+
|
|
403
403
|
Usage:
|
404
404
|
|
405
405
|
<shell>
|
406
|
-
$
|
406
|
+
$ rails profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]
|
407
407
|
</shell>
|
408
408
|
|
409
409
|
Examples:
|
410
410
|
|
411
411
|
<shell>
|
412
|
-
$
|
412
|
+
$ rails profiler 'Item.all'
|
413
413
|
</shell>
|
414
414
|
|
415
415
|
This will profile +Item.all+ in +RubyProf::WALL_TIME+ measure mode. By default, it prints flat output to the shell.
|
416
416
|
|
417
417
|
<shell>
|
418
|
-
$
|
418
|
+
$ rails profiler 'Item.all' 10 graph
|
419
419
|
</shell>
|
420
420
|
|
421
421
|
This will profile +10.times { Item.all }+ with +RubyProf::WALL_TIME+ measure mode and print graph output to the shell.
|
@@ -423,7 +423,7 @@ This will profile +10.times { Item.all }+ with +RubyProf::WALL_TIME+ measure mod
|
|
423
423
|
If you want to store the output in a file:
|
424
424
|
|
425
425
|
<shell>
|
426
|
-
$
|
426
|
+
$ rails profiler 'Item.all' 10 graph 2> graph.txt
|
427
427
|
</shell>
|
428
428
|
|
429
429
|
h3. Helper Methods
|
@@ -39,9 +39,9 @@ The examples in this guide require that you have a working rails application. T
|
|
39
39
|
gem install rails
|
40
40
|
rails yaffle_guide
|
41
41
|
cd yaffle_guide
|
42
|
-
|
42
|
+
rails generate scaffold bird name:string
|
43
43
|
rake db:migrate
|
44
|
-
|
44
|
+
rails server
|
45
45
|
</pre>
|
46
46
|
|
47
47
|
Then navigate to http://localhost:3000/birds. Make sure you have a functioning rails app before continuing.
|
@@ -57,16 +57,16 @@ This creates a plugin in 'vendor/plugins' including an 'init.rb' and 'README' as
|
|
57
57
|
|
58
58
|
Examples:
|
59
59
|
<pre>
|
60
|
-
|
61
|
-
|
60
|
+
rails generate plugin yaffle
|
61
|
+
rails generate plugin yaffle --with-generator
|
62
62
|
</pre>
|
63
63
|
|
64
|
-
To get more detailed help on the plugin generator, type
|
64
|
+
To get more detailed help on the plugin generator, type +rails generate plugin+.
|
65
65
|
|
66
66
|
Later on this guide will describe how to work with generators, so go ahead and generate your plugin with the +--with-generator+ option now:
|
67
67
|
|
68
68
|
<pre>
|
69
|
-
|
69
|
+
rails generate plugin yaffle --with-generator
|
70
70
|
</pre>
|
71
71
|
|
72
72
|
You should see the following output:
|
@@ -104,7 +104,7 @@ To make it easy to organize your files and to make the plugin more compatible wi
|
|
104
104
|
`-- init.rb
|
105
105
|
</pre>
|
106
106
|
|
107
|
-
*vendor/plugins/yaffle/
|
107
|
+
*vendor/plugins/yaffle/init.rb*
|
108
108
|
|
109
109
|
<ruby>
|
110
110
|
require 'yaffle'
|
@@ -334,20 +334,22 @@ end
|
|
334
334
|
To test that your method does what it says it does, run the unit tests with +rake+ from your plugin directory. To see this in action, fire up a console and start squawking:
|
335
335
|
|
336
336
|
<shell>
|
337
|
-
$
|
337
|
+
$ rails console
|
338
338
|
>> "Hello World".to_squawk
|
339
339
|
=> "squawk! Hello World"
|
340
340
|
</shell>
|
341
341
|
|
342
342
|
h4. Working with +init.rb+
|
343
343
|
|
344
|
-
When
|
344
|
+
When Rails loads plugins it looks for a file named +init.rb+. However, when the plugin is initialized, +init.rb+ is invoked via +eval+ (not +require+) so it has slightly different behavior.
|
345
345
|
|
346
|
-
|
346
|
+
NOTE: The plugins loader also looks for +rails/init.rb+, but that one is deprecated in favor of the top-level +init.rb+ aforementioned.
|
347
|
+
|
348
|
+
Under certain circumstances if you reopen classes or modules in +init.rb+ you may inadvertently create a new class, rather than reopening an existing class. A better alternative is to reopen the class in a different file, and require that file from +init.rb+, as shown above.
|
347
349
|
|
348
350
|
If you must reopen a class in +init.rb+ you can use +module_eval+ or +class_eval+ to avoid any issues:
|
349
351
|
|
350
|
-
* *vendor/plugins/yaffle/
|
352
|
+
* *vendor/plugins/yaffle/init.rb*
|
351
353
|
|
352
354
|
<ruby>
|
353
355
|
Hash.class_eval do
|
@@ -359,7 +361,7 @@ end
|
|
359
361
|
|
360
362
|
Another way is to explicitly define the top-level module space for all modules and classes, like +::Hash+:
|
361
363
|
|
362
|
-
* *vendor/plugins/yaffle/
|
364
|
+
* *vendor/plugins/yaffle/init.rb*
|
363
365
|
|
364
366
|
<ruby>
|
365
367
|
class ::Hash
|
@@ -871,7 +873,7 @@ If you plan to distribute your plugin, developers will expect at least a minimum
|
|
871
873
|
Rails ships with several built-in generators. You can see all of the generators available to you by typing the following at the command line:
|
872
874
|
|
873
875
|
<shell>
|
874
|
-
|
876
|
+
rails generate
|
875
877
|
</shell>
|
876
878
|
|
877
879
|
You should see something like this:
|
@@ -882,7 +884,7 @@ Installed Generators
|
|
882
884
|
Builtin: controller, integration_test, mailer, migration, model, observer, plugin, resource, scaffold, session_migration
|
883
885
|
</shell>
|
884
886
|
|
885
|
-
When you run +
|
887
|
+
When you run +rails generate yaffle_definition -h+ you should see the contents of your 'vendor/plugins/yaffle/generators/yaffle_definition/USAGE'.
|
886
888
|
|
887
889
|
For this plugin, update the USAGE file could look like this:
|
888
890
|
|
@@ -1111,11 +1113,11 @@ end
|
|
1111
1113
|
To see this work, type:
|
1112
1114
|
|
1113
1115
|
<shell>
|
1114
|
-
|
1115
|
-
|
1116
|
+
rails generate yaffle_route
|
1117
|
+
rails destroy yaffle_route
|
1116
1118
|
</shell>
|
1117
1119
|
|
1118
|
-
NOTE: If you haven't set up the custom route from above, '
|
1120
|
+
NOTE: If you haven't set up the custom route from above, 'rails destroy' will fail and you'll have to remove it manually.
|
1119
1121
|
|
1120
1122
|
h3. Migrations
|
1121
1123
|
|
@@ -1195,7 +1197,7 @@ h4. Generate Migrations
|
|
1195
1197
|
|
1196
1198
|
Generating migrations has several advantages over other methods. Namely, you can allow other developers to more easily customize the migration. The flow looks like this:
|
1197
1199
|
|
1198
|
-
* call your
|
1200
|
+
* call your rails generate script and pass in whatever options they need
|
1199
1201
|
* examine the generated migration, adding/removing columns or other options as necessary
|
1200
1202
|
|
1201
1203
|
This example will demonstrate how to use one of the built-in generator methods named 'migration_template' to create a migration file. Extending the rails migration generator requires a somewhat intimate knowledge of the migration generator internals, so it's best to write a test first:
|
@@ -1289,7 +1291,7 @@ It's courteous to check to see if table names are being pluralized whenever you
|
|
1289
1291
|
To run the generator, type the following at the command line:
|
1290
1292
|
|
1291
1293
|
<shell>
|
1292
|
-
|
1294
|
+
rails generate yaffle_migration bird
|
1293
1295
|
</shell>
|
1294
1296
|
|
1295
1297
|
and you will see a new file:
|
@@ -1333,15 +1335,15 @@ yaffle:squawk # Prints out the word 'Yaffle'
|
|
1333
1335
|
|
1334
1336
|
You can add as many files as you want in the tasks directory, and if they end in .rake Rails will pick them up.
|
1335
1337
|
|
1336
|
-
Note that tasks from
|
1338
|
+
Note that tasks from +vendor/plugins/yaffle/Rakefile+ are not available to the main app.
|
1337
1339
|
|
1338
|
-
h3.
|
1340
|
+
h3. Plugins as Gems
|
1339
1341
|
|
1340
1342
|
Turning your rails plugin into a gem is a simple and straightforward task. This section will cover how to turn your plugin into a gem. It will not cover how to distribute that gem.
|
1341
1343
|
|
1342
|
-
|
1344
|
+
The initialization file has to be called +rails/init.rb+, the root +init.rb+ file, if any, is ignored by Rails. Also, the name of the plugin now is relevant since +config.gem+ tries to load it. Either name the main file after your gem, or document that users should use the +:lib+ option.
|
1343
1345
|
|
1344
|
-
It's common practice to put any developer-centric rake tasks (such as tests, rdoc and gem package tasks) in
|
1346
|
+
It's common practice to put any developer-centric rake tasks (such as tests, rdoc and gem package tasks) in +Rakefile+. A rake task that packages the gem might look like this:
|
1345
1347
|
|
1346
1348
|
* *vendor/plugins/yaffle/Rakefile:*
|
1347
1349
|
|
@@ -1383,7 +1385,7 @@ rake gem
|
|
1383
1385
|
sudo gem install pkg/yaffle-0.0.1.gem
|
1384
1386
|
</shell>
|
1385
1387
|
|
1386
|
-
To test this, create a new rails app, add
|
1388
|
+
To test this, create a new rails app, add +config.gem "yaffle"+ to +config/environment.rb+ and all of your plugin's functionality will be available to you.
|
1387
1389
|
|
1388
1390
|
h3. RDoc Documentation
|
1389
1391
|
|
@@ -30,11 +30,11 @@ h4. Rails Application's Rack Object
|
|
30
30
|
|
31
31
|
<tt>ActionController::Dispatcher.new</tt> is the primary Rack application object of a Rails application. Any Rack compliant web server should be using +ActionController::Dispatcher.new+ object to serve a Rails application.</p>
|
32
32
|
|
33
|
-
h4. +
|
33
|
+
h4. +rails server+
|
34
34
|
|
35
|
-
<tt>
|
35
|
+
<tt>rails server</tt> does the basic job of creating a +Rack::Builder+ object and starting the webserver. This is Rails' equivalent of Rack's +rackup+ script.
|
36
36
|
|
37
|
-
Here's how +
|
37
|
+
Here's how +rails server+ creates an instance of +Rack::Builder+
|
38
38
|
|
39
39
|
<ruby>
|
40
40
|
app = Rack::Builder.new {
|
@@ -54,7 +54,7 @@ Middlewares used in the code above are primarily useful only in the development
|
|
54
54
|
|
55
55
|
h4. +rackup+
|
56
56
|
|
57
|
-
To use +rackup+ instead of Rails' +
|
57
|
+
To use +rackup+ instead of Rails' +rails server+, you can put the following inside +config.ru+ of your Rails application's root directory:
|
58
58
|
|
59
59
|
<ruby>
|
60
60
|
# RAILS_ROOT/config.ru
|
@@ -233,7 +233,7 @@ h4. Generating a Metal Application
|
|
233
233
|
Rails provides a generator called +metal+ for creating a new Metal application:
|
234
234
|
|
235
235
|
<shell>
|
236
|
-
$
|
236
|
+
$ rails generate metal poller
|
237
237
|
</shell>
|
238
238
|
|
239
239
|
This generates +poller.rb+ in the +app/metal+ directory:
|
@@ -4,7 +4,7 @@ This guide covers the user-facing features of Rails routing. By referring to thi
|
|
4
4
|
|
5
5
|
* Understand the purpose of routing
|
6
6
|
* Decipher the code in +routes.rb+
|
7
|
-
* Construct your own routes, using either the
|
7
|
+
* Construct your own routes, using either the @match@ method or the preferred RESTful style
|
8
8
|
* Identify how a route will map to a controller and action
|
9
9
|
|
10
10
|
endprologue.
|
@@ -37,7 +37,7 @@ Routing also works in reverse. If your application contains this code:
|
|
37
37
|
|
38
38
|
Then the routing engine is the piece that translates that to a link to a URL such as +http://example.com/patients/17+. By using routing in this way, you can reduce the brittleness of your application as compared to one with hard-coded URLs, and make your code easier to read and understand.
|
39
39
|
|
40
|
-
NOTE: Patient needs to be declared as a resource for this style of translation
|
40
|
+
NOTE: Patient needs to be declared as a Restful resource for this style of translation to be available.
|
41
41
|
|
42
42
|
h3. Quick Tour of +routes.rb+
|
43
43
|
|
@@ -45,7 +45,7 @@ There are two components to routing in Rails: the routing engine itself, which i
|
|
45
45
|
|
46
46
|
h4. Processing the File
|
47
47
|
|
48
|
-
In format, +routes.rb+ is nothing more than one big block sent to +
|
48
|
+
In format, +routes.rb+ is nothing more than one big block sent to +ApplicationName::Application.routes.draw+. Within this block, you can have comments, but it's likely that most of your content will be individual lines of code - each line being a route in your application. You'll find five main types of content in this file:
|
49
49
|
|
50
50
|
* RESTful Routes
|
51
51
|
* Named Routes
|
@@ -55,31 +55,39 @@ In format, +routes.rb+ is nothing more than one big block sent to +ActionControl
|
|
55
55
|
|
56
56
|
Each of these types of route is covered in more detail later in this guide.
|
57
57
|
|
58
|
-
The +routes.rb+ file is processed from top to bottom when a request comes in. The request will be dispatched to the first matching route. If there is no matching route, then Rails returns HTTP status 404 to the caller.
|
58
|
+
The +routes.rb+ file is processed from top to bottom when a request comes in. The request will be dispatched to the first matching route, and then proceeds to the next. If there is no matching route, then Rails returns HTTP status 404 to the caller.
|
59
59
|
|
60
60
|
h4. RESTful Routes
|
61
61
|
|
62
|
-
RESTful routes take advantage of the built-in REST orientation of Rails to wrap up a lot of routing information
|
62
|
+
RESTful routes take advantage of the built-in REST orientation of Rails to wrap up a lot of routing information with a single declaration. A RESTful route looks like this:
|
63
63
|
|
64
64
|
<ruby>
|
65
|
-
|
65
|
+
resources :books
|
66
66
|
</ruby>
|
67
67
|
|
68
68
|
h4. Named Routes
|
69
69
|
|
70
70
|
Named routes give you very readable links in your code, as well as handling incoming requests. Here's a typical named route:
|
71
71
|
|
72
|
+
<ruby>
|
73
|
+
match 'login' => 'sessions#new', :as => 'login'
|
74
|
+
</ruby>
|
75
|
+
|
76
|
+
If you're coming from Rails 2, this route will be equivalent to:
|
77
|
+
|
72
78
|
<ruby>
|
73
79
|
map.login '/login', :controller => 'sessions', :action => 'new'
|
74
80
|
</ruby>
|
75
81
|
|
82
|
+
You will also notice that +sessions#new+ is a shorthand for +:controller => 'sessions', :action => 'new'+. By declaring a named route such as this, you can use +login_path+ or +login_url+ in your controllers and views to generate the URLs for this route.
|
83
|
+
|
76
84
|
h4. Nested Routes
|
77
85
|
|
78
86
|
Nested routes let you declare that one resource is contained within another resource. You'll see later on how this translates to URLs and paths in your code. For example, if your application includes parts, each of which belongs to an assembly, you might have this nested route declaration:
|
79
87
|
|
80
88
|
<ruby>
|
81
|
-
|
82
|
-
|
89
|
+
resources :assemblies do
|
90
|
+
resources :parts
|
83
91
|
end
|
84
92
|
</ruby>
|
85
93
|
|
@@ -88,19 +96,18 @@ h4. Regular Routes
|
|
88
96
|
In many applications, you'll also see non-RESTful routing, which explicitly connects the parts of a URL to a particular action. For example,
|
89
97
|
|
90
98
|
<ruby>
|
91
|
-
|
99
|
+
match 'parts/:number' => 'inventory#show'
|
92
100
|
</ruby>
|
93
101
|
|
94
102
|
h4. Default Routes
|
95
103
|
|
96
|
-
The default
|
104
|
+
The default route is a safety net that catches otherwise-unrouted requests. Many Rails applications will contain this default route:
|
97
105
|
|
98
106
|
<ruby>
|
99
|
-
|
100
|
-
map.connect ':controller/:action/:id.:format'
|
107
|
+
match ':controller(/:action(/:id(.:format)))'
|
101
108
|
</ruby>
|
102
109
|
|
103
|
-
|
110
|
+
In Rails 3, this route is commented out advising to use RESTful routes as much as possible. So if you're using RESTful routing for everything in your application, you will probably want to leave it like that.
|
104
111
|
|
105
112
|
h3. RESTful Routing: the Rails Default
|
106
113
|
|
@@ -126,7 +133,7 @@ h4. CRUD, Verbs, and Actions
|
|
126
133
|
In Rails, a RESTful route provides a mapping between HTTP verbs, controller actions, and (implicitly) CRUD operations in a database. A single entry in the routing file, such as
|
127
134
|
|
128
135
|
<ruby>
|
129
|
-
|
136
|
+
resources :photos
|
130
137
|
</ruby>
|
131
138
|
|
132
139
|
creates seven different routes in your application:
|
@@ -142,11 +149,9 @@ creates seven different routes in your application:
|
|
142
149
|
|
143
150
|
For the specific routes (those that reference just a single resource), the identifier for the resource will be available within the corresponding controller action as +params[:id]+.
|
144
151
|
|
145
|
-
TIP: If you consistently use RESTful routes in your application, you should disable the default routes in +routes.rb+ so that Rails will enforce the mapping between HTTP verbs and routes.
|
146
|
-
|
147
152
|
h4. URLs and Paths
|
148
153
|
|
149
|
-
Creating a RESTful route will also make available a pile of helpers within your application:
|
154
|
+
Creating a RESTful route will also make available a pile of helpers within your application, something that requires explicit mention otherwise:
|
150
155
|
|
151
156
|
* +photos_url+ and +photos_path+ map to the path for the index and create actions
|
152
157
|
* +new_photo_url+ and +new_photo_path+ map to the path for the new action
|
@@ -164,26 +169,26 @@ photos_path # => "/photos"
|
|
164
169
|
|
165
170
|
h4. Defining Multiple Resources at the Same Time
|
166
171
|
|
167
|
-
If you need to create routes for more than one RESTful resource, you can save a bit of typing by defining them all with a single call to +
|
172
|
+
If you need to create routes for more than one RESTful resource, you can save a bit of typing by defining them all with a single call to +resources+:
|
168
173
|
|
169
174
|
<ruby>
|
170
|
-
|
175
|
+
resources :photos, :books, :videos
|
171
176
|
</ruby>
|
172
177
|
|
173
178
|
This has exactly the same effect as
|
174
179
|
|
175
180
|
<ruby>
|
176
|
-
|
177
|
-
|
178
|
-
|
181
|
+
resources :photos
|
182
|
+
resources :books
|
183
|
+
resources :videos
|
179
184
|
</ruby>
|
180
185
|
|
181
186
|
h4. Singular Resources
|
182
187
|
|
183
|
-
You can also apply RESTful routing to singleton resources within your application. In this case, you use +
|
188
|
+
You can also apply RESTful routing to singleton resources within your application. In this case, you use +resource+ instead of +resources+ and the route generation is slightly different. For example, a routing entry of
|
184
189
|
|
185
190
|
<ruby>
|
186
|
-
|
191
|
+
resource :geocoder
|
187
192
|
</ruby>
|
188
193
|
|
189
194
|
creates six different routes in your application:
|
@@ -214,19 +219,17 @@ Although the conventions of RESTful routing are likely to be sufficient for many
|
|
214
219
|
* +:conditions+
|
215
220
|
* +:as+
|
216
221
|
* +:path_names+
|
217
|
-
* +:path_prefix+
|
218
|
-
* +:name_prefix+
|
219
222
|
* +:only+
|
220
223
|
* +:except+
|
221
224
|
|
222
|
-
You can also add additional routes via the
|
225
|
+
You can also add additional routes via the +member+ and +collection+ blocks, which are discussed later in this guide.
|
223
226
|
|
224
227
|
h5. Using +:controller+
|
225
228
|
|
226
229
|
The +:controller+ option lets you use a controller name that is different from the public-facing resource name. For example, this routing entry:
|
227
230
|
|
228
231
|
<ruby>
|
229
|
-
|
232
|
+
resources :photos, :controller => "images"
|
230
233
|
</ruby>
|
231
234
|
|
232
235
|
will recognize incoming URLs containing +photo+ but route the requests to the Images controller:
|
@@ -247,35 +250,37 @@ h4. Controller Namespaces and Routing
|
|
247
250
|
Rails allows you to group your controllers into namespaces by saving them in folders underneath +app/controllers+. The +:controller+ option provides a convenient way to use these routes. For example, you might have a resource whose controller is purely for admin users in the +admin+ folder:
|
248
251
|
|
249
252
|
<ruby>
|
250
|
-
|
253
|
+
resources :photos, :controller => "admin/photos"
|
251
254
|
</ruby>
|
252
255
|
|
253
|
-
If you use controller namespaces, you need to be aware of a subtlety in the Rails routing code: it always tries to preserve as much of the namespace from the previous request as possible. For example, if you are on a view generated from the +
|
256
|
+
If you use controller namespaces, you need to be aware of a subtlety in the Rails routing code: it always tries to preserve as much of the namespace from the previous request as possible. For example, if you are on a view generated from the +photo_path+ helper, and you follow a link generated with +<%= link_to "show", photo_path(1) %>+ you will end up on the view generated by +admin/photos/show+, but you will also end up in the same place if you have +<%= link_to "show", {:controller => "photos", :action => "show"} %>+ because Rails will generate the show URL relative to the current URL.
|
254
257
|
|
255
258
|
TIP: If you want to guarantee that a link goes to a top-level controller, use a preceding slash to anchor the controller name: +<%= link_to "show", {:controller => "/photos", :action => "show"} %>+
|
256
259
|
|
257
260
|
You can also specify a controller namespace with the +:namespace+ option instead of a path:
|
258
261
|
|
259
262
|
<ruby>
|
260
|
-
|
263
|
+
resources :adminphotos, :namespace => "admin", :controller => "photos"
|
261
264
|
</ruby>
|
262
265
|
|
263
|
-
This can be especially useful when
|
266
|
+
This can be especially useful when map multiple namespaced routes together using +namespace+ block by:
|
264
267
|
|
265
268
|
<ruby>
|
266
|
-
|
267
|
-
|
269
|
+
namespace :admin do
|
270
|
+
resources :photos, :videos
|
268
271
|
end
|
269
272
|
</ruby>
|
270
273
|
|
271
|
-
That would give you routing for +admin/photos+ and +admin/videos+ controllers.
|
274
|
+
That would give you routing for +admin/photos+ and +admin/videos+ controllers.
|
275
|
+
|
276
|
+
The difference between generating routes through +namespace+ and the +:controller+ key is that the +namespace+ will add +admin+ to the generated helpers as well, so the above route generates +admin_photos_path+.
|
272
277
|
|
273
278
|
h5. Using +:singular+
|
274
279
|
|
275
280
|
If for some reason Rails isn't doing what you want in converting the plural resource name to a singular name in member routes, you can override its judgment with the +:singular+ option:
|
276
281
|
|
277
282
|
<ruby>
|
278
|
-
|
283
|
+
resources :teeth, :singular => "tooth"
|
279
284
|
</ruby>
|
280
285
|
|
281
286
|
TIP: Depending on the other code in your application, you may prefer to add additional rules to the +Inflector+ class instead.
|
@@ -285,7 +290,7 @@ h5. Using +:requirements+
|
|
285
290
|
You can use the +:requirements+ option in a RESTful route to impose a format on the implied +:id+ parameter in the singular routes. For example:
|
286
291
|
|
287
292
|
<ruby>
|
288
|
-
|
293
|
+
resources :photos, :requirements => {:id => /[A-Z][A-Z][0-9]+/}
|
289
294
|
</ruby>
|
290
295
|
|
291
296
|
This declaration constrains the +:id+ parameter to match the supplied regular expression. So, in this case, +/photos/1+ would no longer be recognized by this route, but +/photos/RR27+ would.
|
@@ -299,7 +304,7 @@ h5. Using +:as+
|
|
299
304
|
The +:as+ option lets you override the normal naming for the actual generated paths. For example:
|
300
305
|
|
301
306
|
<ruby>
|
302
|
-
|
307
|
+
resources :photos, :as => "images"
|
303
308
|
</ruby>
|
304
309
|
|
305
310
|
will recognize incoming URLs containing +image+ but route the requests to the Photos controller:
|
@@ -320,7 +325,7 @@ h5. Using +:path_names+
|
|
320
325
|
The +:path_names+ option lets you override the automatically-generated "new" and "edit" segments in URLs:
|
321
326
|
|
322
327
|
<ruby>
|
323
|
-
|
328
|
+
resources :photos, :path_names => { :new => 'make', :edit => 'change' }
|
324
329
|
</ruby>
|
325
330
|
|
326
331
|
This would cause the routing to recognize URLs such as
|
@@ -343,7 +348,7 @@ h5. Using +:path_prefix+
|
|
343
348
|
The +:path_prefix+ option lets you add additional parameters that will be prefixed to the recognized paths. For example, suppose each photo in your application belongs to a particular photographer. In that case, you might declare this route:
|
344
349
|
|
345
350
|
<ruby>
|
346
|
-
|
351
|
+
resources :photos, :path_prefix => '/photographers/:photographer_id'
|
347
352
|
</ruby>
|
348
353
|
|
349
354
|
Routes recognized by this entry would include:
|
@@ -362,9 +367,9 @@ h5. Using +:name_prefix+
|
|
362
367
|
You can use the :name_prefix option to avoid collisions between routes. This is most useful when you have two resources with the same name that use +:path_prefix+ to map differently. For example:
|
363
368
|
|
364
369
|
<ruby>
|
365
|
-
|
370
|
+
resources :photos, :path_prefix => '/photographers/:photographer_id',
|
366
371
|
:name_prefix => 'photographer_'
|
367
|
-
|
372
|
+
resources :photos, :path_prefix => '/agencies/:agency_id',
|
368
373
|
:name_prefix => 'agency_'
|
369
374
|
</ruby>
|
370
375
|
|
@@ -377,7 +382,7 @@ h5. Using +:only+ and +:except+
|
|
377
382
|
By default, Rails creates routes for all seven of the default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application. You can use the +:only+ and +:except+ options to fine-tune this behavior. The +:only+ option specifies that only certain routes should be generated:
|
378
383
|
|
379
384
|
<ruby>
|
380
|
-
|
385
|
+
resources :photos, :only => [:index, :show]
|
381
386
|
</ruby>
|
382
387
|
|
383
388
|
With this declaration, a +GET+ request to +/photos+ would succeed, but a +POST+ request to +/photos+ (which would ordinarily be routed to the create action) will fail.
|
@@ -385,7 +390,7 @@ With this declaration, a +GET+ request to +/photos+ would succeed, but a +POST+
|
|
385
390
|
The +:except+ option specifies a route or list of routes that should _not_ be generated:
|
386
391
|
|
387
392
|
<ruby>
|
388
|
-
|
393
|
+
resources :photos, :except => :destroy
|
389
394
|
</ruby>
|
390
395
|
|
391
396
|
In this case, all of the normal routes except the route for +destroy+ (a +DELETE+ request to +/photos/<em>id</em>+) will be generated.
|
@@ -411,12 +416,12 @@ end
|
|
411
416
|
Each ad is logically subservient to one magazine. Nested routes allow you to capture this relationship in your routing. In this case, you might include this route declaration:
|
412
417
|
|
413
418
|
<ruby>
|
414
|
-
|
415
|
-
|
419
|
+
resources :magazines do
|
420
|
+
resources :ads
|
416
421
|
end
|
417
422
|
</ruby>
|
418
423
|
|
419
|
-
TIP: Further below you'll learn about a convenient shortcut for this construct:<br/>+
|
424
|
+
TIP: Further below you'll learn about a convenient shortcut for this construct:<br/>+resources :magazines, :has_many => :ads+
|
420
425
|
|
421
426
|
In addition to the routes for magazines, this declaration will also create routes for ads, each of which requires the specification of a magazine in the URL:
|
422
427
|
|
@@ -437,16 +442,16 @@ h5. Using +:name_prefix+
|
|
437
442
|
The +:name_prefix+ option overrides the automatically-generated prefix in nested route helpers. For example,
|
438
443
|
|
439
444
|
<ruby>
|
440
|
-
|
441
|
-
|
445
|
+
resources :magazines do
|
446
|
+
resources :ads, :name_prefix => 'periodical'
|
442
447
|
end
|
443
448
|
</ruby>
|
444
449
|
|
445
450
|
This will create routing helpers such as +periodical_ads_url+ and +periodical_edit_ad_path+. You can even use +:name_prefix+ to suppress the prefix entirely:
|
446
451
|
|
447
452
|
<ruby>
|
448
|
-
|
449
|
-
|
453
|
+
resources :magazines do
|
454
|
+
resources :ads, :name_prefix => nil
|
450
455
|
end
|
451
456
|
</ruby>
|
452
457
|
|
@@ -462,16 +467,16 @@ h5. Using +:has_one+ and +:has_many+
|
|
462
467
|
The +:has_one+ and +:has_many+ options provide a succinct notation for simple nested routes. Use +:has_one+ to nest a singleton resource, or +:has_many+ to nest a plural resource:
|
463
468
|
|
464
469
|
<ruby>
|
465
|
-
|
470
|
+
resources :photos, :has_one => :photographer, :has_many => [:publications, :versions]
|
466
471
|
</ruby>
|
467
472
|
|
468
473
|
This has the same effect as this set of declarations:
|
469
474
|
|
470
475
|
<ruby>
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
476
|
+
resources :photos do
|
477
|
+
resource :photographer
|
478
|
+
resources :publications
|
479
|
+
resources :versions
|
475
480
|
end
|
476
481
|
</ruby>
|
477
482
|
|
@@ -480,9 +485,9 @@ h5. Limits to Nesting
|
|
480
485
|
You can nest resources within other nested resources if you like. For example:
|
481
486
|
|
482
487
|
<ruby>
|
483
|
-
|
484
|
-
|
485
|
-
|
488
|
+
resources :publishers do
|
489
|
+
resources :magazines do
|
490
|
+
resources :photos
|
486
491
|
end
|
487
492
|
end
|
488
493
|
</ruby>
|
@@ -502,9 +507,9 @@ h5. Shallow Nesting
|
|
502
507
|
The +:shallow+ option provides an elegant solution to the difficulties of deeply-nested routes. If you specify this option at any level of routing, then paths for nested resources which reference a specific member (that is, those with an +:id+ parameter) will not use the parent path prefix or name prefix. To see what this means, consider this set of routes:
|
503
508
|
|
504
509
|
<ruby>
|
505
|
-
|
506
|
-
|
507
|
-
|
510
|
+
resources :publishers, :shallow => true do
|
511
|
+
resources :magazines do
|
512
|
+
resources :photos
|
508
513
|
end
|
509
514
|
end
|
510
515
|
</ruby>
|
@@ -522,7 +527,7 @@ This will enable recognition of (among others) these routes:
|
|
522
527
|
With shallow nesting, you need only supply enough information to uniquely identify the resource that you want to work with. If you like, you can combine shallow nesting with the +:has_one+ and +:has_many+ options:
|
523
528
|
|
524
529
|
<ruby>
|
525
|
-
|
530
|
+
resources :publishers, :has_many => { :magazines => :photos }, :shallow => true
|
526
531
|
</ruby>
|
527
532
|
|
528
533
|
h4. Route Generation from Arrays
|
@@ -530,8 +535,8 @@ h4. Route Generation from Arrays
|
|
530
535
|
In addition to using the generated routing helpers, Rails can also generate RESTful routes from an array of parameters. For example, suppose you have a set of routes generated with these entries in routes.rb:
|
531
536
|
|
532
537
|
<ruby>
|
533
|
-
|
534
|
-
|
538
|
+
resources :magazines do
|
539
|
+
resources :ads
|
535
540
|
end
|
536
541
|
</ruby>
|
537
542
|
|
@@ -554,17 +559,16 @@ h4. Namespaced Resources
|
|
554
559
|
It's possible to do some quite complex things by combining +:path_prefix+ and +:name_prefix+. For example, you can use the combination of these two options to move administrative resources to their own folder in your application:
|
555
560
|
|
556
561
|
<ruby>
|
557
|
-
|
558
|
-
|
559
|
-
|
562
|
+
resources :photos, :path_prefix => 'admin', :controller => 'admin/photos'
|
563
|
+
resources :tags, :name_prefix => 'admin_photo_', :path_prefix => 'admin/photos/:photo_id', :controller => 'admin/photo_tags'
|
564
|
+
resources :ratings, :name_prefix => 'admin_photo_', :path_prefix => 'admin/photos/:photo_id', :controller => 'admin/photo_ratings'
|
560
565
|
</ruby>
|
561
566
|
|
562
567
|
The good news is that if you find yourself using this level of complexity, you can stop. Rails supports _namespaced resources_ to make placing resources in their own folder a snap. Here's the namespaced version of those same three routes:
|
563
568
|
|
564
569
|
<ruby>
|
565
|
-
|
566
|
-
|
567
|
-
:has_many => { :tags, :ratings}
|
570
|
+
namespace :admin do
|
571
|
+
resources :photos, :has_many => { :tags, :ratings }
|
568
572
|
end
|
569
573
|
</ruby>
|
570
574
|
|
@@ -576,18 +580,24 @@ You are not limited to the seven routes that RESTful routing creates by default.
|
|
576
580
|
|
577
581
|
h5. Adding Member Routes
|
578
582
|
|
579
|
-
To add a member route,
|
583
|
+
To add a member route, just add +member+ block into resource block:
|
580
584
|
|
581
585
|
<ruby>
|
582
|
-
|
586
|
+
resources :photos do
|
587
|
+
member do
|
588
|
+
get :preview
|
589
|
+
end
|
590
|
+
end
|
583
591
|
</ruby>
|
584
592
|
|
585
593
|
This will enable Rails to recognize URLs such as +/photos/1/preview+ using the GET HTTP verb, and route them to the preview action of the Photos controller. It will also create the +preview_photo_url+ and +preview_photo_path+ route helpers.
|
586
594
|
|
587
|
-
Within the
|
595
|
+
Within the block of member routes, each route name specifies the HTTP verb that it will recognize. You can use +get+, +put+, +post+, +delete+, or +any+ here. If you don't have multiple +member+ route, you can also passing +:on+ to the routing.
|
588
596
|
|
589
597
|
<ruby>
|
590
|
-
|
598
|
+
resources :photos do
|
599
|
+
get :preview, :on => :member
|
600
|
+
end
|
591
601
|
</ruby>
|
592
602
|
|
593
603
|
h5. Adding Collection Routes
|
@@ -595,32 +605,35 @@ h5. Adding Collection Routes
|
|
595
605
|
To add a collection route, use the +:collection+ option:
|
596
606
|
|
597
607
|
<ruby>
|
598
|
-
|
608
|
+
resources :photos do
|
609
|
+
collection do
|
610
|
+
get :search
|
611
|
+
end
|
612
|
+
end
|
599
613
|
</ruby>
|
600
614
|
|
601
615
|
This will enable Rails to recognize URLs such as +/photos/search+ using the GET HTTP verb, and route them to the search action of the Photos controller. It will also create the +search_photos_url+ and +search_photos_path+ route helpers.
|
602
616
|
|
603
|
-
Just as with member routes, you can
|
617
|
+
Just as with member routes, you can passing +:on+ to the routing.
|
604
618
|
|
605
619
|
<ruby>
|
606
|
-
|
620
|
+
resources :photos do
|
621
|
+
get :search, :on => :collection
|
622
|
+
end
|
607
623
|
</ruby>
|
608
624
|
|
609
625
|
h5. Adding New Routes
|
610
626
|
|
611
|
-
|
627
|
+
As of writing, Rails 3 has deprecated +:new+ option from routing. You will need to explicit define the route using +match+ method
|
612
628
|
|
613
629
|
<ruby>
|
614
|
-
|
630
|
+
resources :photos
|
631
|
+
match 'photos/new/upload' => 'photos#upload', :as => 'upload_new_photos'
|
615
632
|
</ruby>
|
616
633
|
|
617
|
-
This will enable Rails to recognize URLs such as +/photos/new/upload+ using the POST HTTP verb, and route them to the upload action of the Photos controller. It will also create the +upload_new_photos_path+ and +upload_new_photos_url+ route helpers.
|
618
|
-
|
619
|
-
TIP: If you want to redefine the verbs accepted by one of the standard actions, you can do so by explicitly mapping that action. For example:<br/>+map.resources :photos, :new => { :new => :any }+<br/>This will allow the new action to be invoked by any request to +photos/new+, no matter what HTTP verb you use.
|
620
|
-
|
621
634
|
h5. A Note of Caution
|
622
635
|
|
623
|
-
If you find yourself adding many extra actions to a RESTful route, it's time to stop and ask yourself whether you're disguising the presence of another resource that would be better split off on its own. When the
|
636
|
+
If you find yourself adding many extra actions to a RESTful route, it's time to stop and ask yourself whether you're disguising the presence of another resource that would be better split off on its own. When the +member+ and +collection+ hashes become a dumping-ground, RESTful routes lose the advantage of easy readability that is one of their strongest points.
|
624
637
|
|
625
638
|
h3. Regular Routes
|
626
639
|
|
@@ -633,7 +646,7 @@ h4. Bound Parameters
|
|
633
646
|
When you set up a regular route, you supply a series of symbols that Rails maps to parts of an incoming HTTP request. Two of these symbols are special: +:controller+ maps to the name of a controller in your application, and +:action+ maps to the name of an action within that controller. For example, consider one of the default Rails routes:
|
634
647
|
|
635
648
|
<ruby>
|
636
|
-
|
649
|
+
match ':controller(/:action(/:id))'
|
637
650
|
</ruby>
|
638
651
|
|
639
652
|
If an incoming request of +/photos/show/1+ is processed by this route (because it hasn't matched any previous route in the file), then the result will be to invoke the +show+ action of the +Photos+ controller, and to make the final parameter (1) available as +params[:id]+.
|
@@ -643,7 +656,7 @@ h4. Wildcard Components
|
|
643
656
|
You can set up as many wildcard symbols within a regular route as you like. Anything other than +:controller+ or +:action+ will be available to the matching action as part of the params hash. So, if you set up this route:
|
644
657
|
|
645
658
|
<ruby>
|
646
|
-
|
659
|
+
match ':controller/:action/:id/:user_id'
|
647
660
|
</ruby>
|
648
661
|
|
649
662
|
An incoming URL of +/photos/show/1/2+ will be dispatched to the +show+ action of the +Photos+ controller. +params[:id]+ will be set to 1, and +params[:user_id]+ will be set to 2.
|
@@ -653,7 +666,7 @@ h4. Static Text
|
|
653
666
|
You can specify static text when creating a route. In this case, the static text is used only for matching the incoming requests:
|
654
667
|
|
655
668
|
<ruby>
|
656
|
-
|
669
|
+
match ':controller/:action/:id/with_user/:user_id'
|
657
670
|
</ruby>
|
658
671
|
|
659
672
|
This route would respond to URLs such as +/photos/show/1/with_user/2+.
|
@@ -663,17 +676,17 @@ h4. Querystring Parameters
|
|
663
676
|
Rails routing automatically picks up querystring parameters and makes them available in the +params+ hash. For example, with this route:
|
664
677
|
|
665
678
|
<ruby>
|
666
|
-
|
679
|
+
match ':controller/:action/:id
|
667
680
|
</ruby>
|
668
681
|
|
669
682
|
An incoming URL of +/photos/show/1?user_id=2+ will be dispatched to the +show+ action of the +Photos+ controller. +params[:id]+ will be set to 1, and +params[:user_id]+ will be equal to 2.
|
670
683
|
|
671
684
|
h4. Defining Defaults
|
672
685
|
|
673
|
-
You do not need to explicitly use the +:controller+ and +:action+ symbols within a route. You can supply defaults for these two parameters
|
686
|
+
You do not need to explicitly use the +:controller+ and +:action+ symbols within a route. You can supply defaults for these two parameters by putting it after +=>+:
|
674
687
|
|
675
688
|
<ruby>
|
676
|
-
|
689
|
+
match 'photos/:id' => 'photos#show'
|
677
690
|
</ruby>
|
678
691
|
|
679
692
|
With this route, an incoming URL of +/photos/12+ would be dispatched to the +show+ action within the +Photos+ controller.
|
@@ -681,8 +694,7 @@ With this route, an incoming URL of +/photos/12+ would be dispatched to the +sho
|
|
681
694
|
You can also define other defaults in a route by supplying a hash for the +:defaults+ option. This even applies to parameters that are not explicitly defined elsewhere in the route. For example:
|
682
695
|
|
683
696
|
<ruby>
|
684
|
-
|
685
|
-
:defaults => { :format => 'jpg' }
|
697
|
+
match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' }
|
686
698
|
</ruby>
|
687
699
|
|
688
700
|
With this route, an incoming URL of +photos/12+ would be dispatched to the +show+ action within the +Photos+ controller, and +params[:format]+ will be set to +jpg+.
|
@@ -692,7 +704,7 @@ h4. Named Routes
|
|
692
704
|
Regular routes need not use the +connect+ method. You can use any other name here to create a _named route_. For example,
|
693
705
|
|
694
706
|
<ruby>
|
695
|
-
|
707
|
+
match 'logout' => 'sessions#destroy', :as => :logout
|
696
708
|
</ruby>
|
697
709
|
|
698
710
|
This will do two things. First, requests to +/logout+ will be sent to the +destroy+ action of the +Sessions+ controller. Second, Rails will maintain the +logout_path+ and +logout_url+ helpers for use within your code.
|
@@ -702,15 +714,13 @@ h4. Route Requirements
|
|
702
714
|
You can use the +:requirements+ option to enforce a format for any parameter in a route:
|
703
715
|
|
704
716
|
<ruby>
|
705
|
-
|
706
|
-
:requirements => { :id => /[A-Z]\d{5}/ }
|
717
|
+
match 'photo/:id' => 'photos#show', :requirements => { :id => /[A-Z]\d{5}/ }
|
707
718
|
</ruby>
|
708
719
|
|
709
720
|
This route would respond to URLs such as +/photo/A12345+. You can more succinctly express the same route this way:
|
710
721
|
|
711
722
|
<ruby>
|
712
|
-
|
713
|
-
:id => /[A-Z]\d{5}/
|
723
|
+
match 'photo/:id' => 'photos#show', :id => /[A-Z]\d{5}/
|
714
724
|
</ruby>
|
715
725
|
|
716
726
|
h4. Route Conditions
|
@@ -718,8 +728,7 @@ h4. Route Conditions
|
|
718
728
|
Route conditions (introduced with the +:conditions+ option) are designed to implement restrictions on routes. Currently, the only supported restriction is +:method+:
|
719
729
|
|
720
730
|
<ruby>
|
721
|
-
|
722
|
-
:conditions => { :method => :get }
|
731
|
+
match 'photo/:id' => 'photos#show', :conditions => { :method => :get }
|
723
732
|
</ruby>
|
724
733
|
|
725
734
|
As with conditions in RESTful routes, you can specify +:get+, +:post+, +:put+, +:delete+, or +:any+ for the acceptable method.
|
@@ -729,7 +738,7 @@ h4. Route Globbing
|
|
729
738
|
Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example
|
730
739
|
|
731
740
|
<ruby>
|
732
|
-
|
741
|
+
match 'photo/*other' => 'photos#unknown'
|
733
742
|
</ruby>
|
734
743
|
|
735
744
|
This route would match +photo/12+ or +/photo/long/path/to/12+ equally well, creating an array of path segments as the value of +params[:other]+.
|
@@ -755,7 +764,7 @@ There's one more way in which routing can do different things depending on diffe
|
|
755
764
|
For instance, consider the second of the default routes in the boilerplate +routes.rb+ file:
|
756
765
|
|
757
766
|
<ruby>
|
758
|
-
|
767
|
+
match ':controller(/:action(/:id(.:format)))'
|
759
768
|
</ruby>
|
760
769
|
|
761
770
|
This route matches requests such as +/photo/edit/1.xml+ or +/photo/show/2.rss+. Within the appropriate action code, you can issue different responses depending on the requested format:
|
@@ -781,11 +790,10 @@ Mime::Type.register "image/jpg", :jpg
|
|
781
790
|
|
782
791
|
h3. The Default Routes
|
783
792
|
|
784
|
-
When you create a new Rails application, +routes.rb+ is initialized with
|
793
|
+
When you create a new Rails application, +routes.rb+ is initialized with a default route:
|
785
794
|
|
786
795
|
<ruby>
|
787
|
-
|
788
|
-
map.connect ':controller/:action/:id.:format'
|
796
|
+
match ':controller(/:action(/:id(.:format)))'
|
789
797
|
</ruby>
|
790
798
|
|
791
799
|
These routes provide reasonable defaults for many URLs, if you're not using RESTful routing.
|
@@ -796,31 +804,24 @@ h3. The Empty Route
|
|
796
804
|
|
797
805
|
Don't confuse the default routes with the empty route. The empty route has one specific purpose: to route requests that come in to the root of the web site. For example, if your site is example.com, then requests to +http://example.com+ or +http://example.com/+ will be handled by the empty route.
|
798
806
|
|
799
|
-
h4. Using +
|
807
|
+
h4. Using +root+
|
800
808
|
|
801
|
-
The preferred way to set up the empty route is with the +
|
809
|
+
The preferred way to set up the empty route is with the +root+ command:
|
802
810
|
|
803
811
|
<ruby>
|
804
|
-
|
812
|
+
root :to => 'pages#main'
|
805
813
|
</ruby>
|
806
814
|
|
807
815
|
The use of the +root+ method tells Rails that this route applies to requests for the root of the site.
|
808
816
|
|
809
|
-
|
810
|
-
|
811
|
-
<ruby>
|
812
|
-
map.index 'index', :controller => "pages", :action => "main"
|
813
|
-
map.root :index
|
814
|
-
</ruby>
|
815
|
-
|
816
|
-
Because of the top-down processing of the file, the named route must be specified _before_ the call to +map.root+.
|
817
|
+
Because of the top-down processing of the file, the named route must be specified _before_ the call to +root+.
|
817
818
|
|
818
819
|
h4. Connecting the Empty String
|
819
820
|
|
820
821
|
You can also specify an empty route by explicitly connecting the empty string:
|
821
822
|
|
822
823
|
<ruby>
|
823
|
-
|
824
|
+
match '' => 'pages#main'
|
824
825
|
</ruby>
|
825
826
|
|
826
827
|
TIP: If the empty route does not seem to be working in your application, make sure that you have deleted the file +public/index.html+ from your Rails tree.
|
@@ -898,6 +899,7 @@ h3. Changelog
|
|
898
899
|
|
899
900
|
"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/3
|
900
901
|
|
902
|
+
* Febuary 1, 2010: Modifies the routing documentation to match new routing DSL in Rails 3, by Prem Sichanugrist
|
901
903
|
* October 4, 2008: Added additional detail on specifying verbs for resource member/collection routes, by "Mike Gunderloy":credits.html#mgunderloy
|
902
904
|
* September 23, 2008: Added section on namespaced controllers and routing, by "Mike Gunderloy":credits.html#mgunderloy
|
903
905
|
* September 10, 2008: initial version by "Mike Gunderloy":credits.html#mgunderloy
|