railties 3.0.20 → 3.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +36 -49
- data/README.rdoc +2 -1
- data/guides/assets/stylesheets/fixes.css +16 -0
- data/guides/rails_guides.rb +2 -2
- data/guides/rails_guides/generator.rb +8 -3
- data/guides/rails_guides/textile_extensions.rb +4 -2
- data/guides/source/2_2_release_notes.textile +3 -3
- data/guides/source/2_3_release_notes.textile +2 -2
- data/guides/source/3_0_release_notes.textile +14 -14
- data/guides/source/action_controller_overview.textile +54 -79
- data/guides/source/action_mailer_basics.textile +39 -9
- data/guides/source/action_view_overview.textile +257 -211
- data/guides/source/active_record_basics.textile +1 -1
- data/guides/source/active_record_querying.textile +217 -27
- data/guides/source/active_record_validations_callbacks.textile +94 -25
- data/guides/source/active_support_core_extensions.textile +109 -77
- data/guides/source/ajax_on_rails.textile +15 -150
- data/guides/source/api_documentation_guidelines.textile +12 -12
- data/guides/source/association_basics.textile +74 -60
- data/guides/source/caching_with_rails.textile +59 -60
- data/guides/source/command_line.textile +46 -47
- data/guides/source/configuring.textile +55 -37
- data/guides/source/contribute.textile +7 -7
- data/guides/source/contributing_to_ruby_on_rails.textile +14 -23
- data/guides/source/credits.html.erb +3 -3
- data/guides/source/debugging_rails_applications.textile +59 -46
- data/guides/source/form_helpers.textile +76 -31
- data/guides/source/generators.textile +39 -40
- data/guides/source/getting_started.textile +73 -94
- data/guides/source/i18n.textile +64 -58
- data/guides/source/index.html.erb +3 -3
- data/guides/source/initialization.textile +634 -3284
- data/guides/source/layout.html.erb +6 -7
- data/guides/source/layouts_and_rendering.textile +59 -60
- data/guides/source/migrations.textile +63 -59
- data/guides/source/nested_model_forms.textile +2 -2
- data/guides/source/performance_testing.textile +16 -16
- data/guides/source/plugins.textile +236 -1280
- data/guides/source/rails_application_templates.textile +37 -29
- data/guides/source/rails_on_rack.textile +4 -9
- data/guides/source/routing.textile +96 -75
- data/guides/source/ruby_on_rails_guides_guidelines.textile +19 -12
- data/guides/source/security.textile +57 -30
- data/guides/source/testing.textile +26 -24
- data/guides/w3c_validator.rb +2 -2
- data/lib/rails.rb +1 -7
- data/lib/rails/application.rb +46 -76
- data/lib/rails/application/bootstrap.rb +6 -11
- data/lib/rails/application/configuration.rb +43 -40
- data/lib/rails/application/finisher.rb +16 -4
- data/lib/rails/application/railties.rb +6 -24
- data/lib/rails/application/routes_reloader.rb +45 -0
- data/lib/rails/backtrace_cleaner.rb +1 -1
- data/lib/rails/cli.rb +7 -5
- data/lib/rails/commands.rb +27 -2
- data/lib/rails/commands/application.rb +14 -1
- data/lib/rails/commands/benchmarker.rb +3 -1
- data/lib/rails/commands/dbconsole.rb +2 -2
- data/lib/rails/commands/destroy.rb +3 -1
- data/lib/rails/commands/generate.rb +3 -1
- data/lib/rails/commands/plugin.rb +2 -7
- data/lib/rails/commands/plugin_new.rb +10 -0
- data/lib/rails/commands/profiler.rb +3 -1
- data/lib/rails/commands/server.rb +4 -0
- data/lib/rails/configuration.rb +8 -81
- data/lib/rails/console/app.rb +2 -2
- data/lib/rails/engine.rb +460 -78
- data/lib/rails/engine/configuration.rb +46 -49
- data/lib/rails/engine/railties.rb +33 -0
- data/lib/rails/generators.rb +11 -5
- data/lib/rails/generators/actions.rb +2 -27
- data/lib/rails/generators/app_base.rb +216 -0
- data/lib/rails/generators/base.rb +3 -2
- data/lib/rails/generators/erb/scaffold/templates/index.html.erb +1 -1
- data/lib/rails/generators/generated_attribute.rb +2 -1
- data/lib/rails/generators/migration.rb +6 -2
- data/lib/rails/generators/named_base.rb +79 -3
- data/lib/rails/generators/rails/app/app_generator.rb +44 -209
- data/lib/rails/generators/rails/app/templates/Gemfile +15 -31
- data/lib/rails/generators/rails/app/templates/README +2 -2
- data/lib/rails/generators/rails/app/templates/Rakefile +1 -1
- data/lib/rails/generators/rails/app/templates/{public → app/assets}/images/rails.png +0 -0
- data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +8 -0
- data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +5 -0
- data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/app/models/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +4 -4
- data/lib/rails/generators/rails/app/templates/config/application.rb +19 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +4 -4
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +11 -6
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -1
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +1 -2
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +14 -11
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt +12 -0
- data/lib/rails/generators/rails/app/templates/config/locales/en.yml +1 -1
- data/lib/rails/generators/rails/app/templates/config/routes.rb +1 -1
- data/lib/rails/generators/rails/app/templates/db/{seeds.rb → seeds.rb.tt} +2 -2
- data/lib/rails/generators/rails/app/templates/public/index.html +10 -8
- data/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/test/functional/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/test/integration/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/test/{test_helper.rb.tt → test_helper.rb} +0 -0
- data/lib/rails/generators/rails/app/templates/test/unit/.empty_directory +0 -0
- data/lib/rails/generators/rails/assets/USAGE +20 -0
- data/lib/rails/generators/rails/assets/assets_generator.rb +39 -0
- data/lib/rails/generators/rails/assets/templates/javascript.js +2 -0
- data/lib/rails/generators/rails/assets/templates/javascript.js.coffee +3 -0
- data/lib/rails/generators/rails/assets/templates/stylesheet.css +4 -0
- data/lib/rails/generators/rails/assets/templates/stylesheet.css.scss +5 -0
- data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
- data/lib/rails/generators/rails/controller/templates/controller.rb +2 -0
- data/lib/rails/generators/rails/generator/generator_generator.rb +2 -2
- data/lib/rails/generators/rails/generator/templates/templates/.empty_directory +0 -0
- data/lib/rails/generators/rails/helper/templates/helper.rb +2 -0
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +7 -0
- data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +4 -4
- data/lib/rails/generators/rails/plugin_new/USAGE +10 -0
- data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +303 -0
- data/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +9 -0
- data/lib/rails/generators/rails/plugin_new/templates/Gemfile +11 -0
- data/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE +20 -0
- data/lib/rails/generators/rails/plugin_new/templates/README.rdoc +3 -0
- data/lib/rails/generators/rails/plugin_new/templates/Rakefile +21 -0
- data/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt +4 -0
- data/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt +4 -0
- data/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory +0 -0
- data/lib/rails/generators/rails/plugin_new/templates/config/routes.rb +6 -0
- data/lib/rails/generators/rails/plugin_new/templates/gitignore +6 -0
- data/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb +6 -0
- data/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb +7 -0
- data/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake +4 -0
- data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +16 -0
- data/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb +10 -0
- data/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb +4 -0
- data/lib/rails/generators/rails/plugin_new/templates/script/rails.tt +5 -0
- data/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb +7 -0
- data/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb +12 -0
- data/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb +10 -0
- data/lib/rails/generators/rails/resource/resource_generator.rb +2 -2
- data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +20 -1
- data/lib/rails/generators/rails/{stylesheets → scaffold}/templates/scaffold.css +0 -0
- data/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss +58 -0
- data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +21 -19
- data/lib/rails/generators/resource_helpers.rb +3 -3
- data/lib/rails/generators/test_case.rb +2 -20
- data/lib/rails/generators/test_unit/controller/templates/functional_test.rb +5 -4
- data/lib/rails/generators/test_unit/helper/templates/helper_test.rb +2 -0
- data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +3 -4
- data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb +5 -4
- data/lib/rails/generators/test_unit/model/templates/fixtures.yml +1 -1
- data/lib/rails/generators/test_unit/model/templates/unit_test.rb +5 -4
- data/lib/rails/generators/test_unit/observer/templates/unit_test.rb +5 -4
- data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +3 -4
- data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +7 -5
- data/lib/rails/info.rb +0 -1
- data/lib/rails/paths.rb +119 -65
- data/lib/rails/plugin.rb +18 -19
- data/lib/rails/rack/log_tailer.rb +1 -1
- data/lib/rails/railtie.rb +50 -47
- data/lib/rails/railtie/configurable.rb +20 -10
- data/lib/rails/railtie/configuration.rb +20 -19
- data/lib/rails/source_annotation_extractor.rb +5 -5
- data/lib/rails/tasks.rb +1 -0
- data/lib/rails/tasks/assets.rake +10 -0
- data/lib/rails/tasks/documentation.rake +2 -8
- data/lib/rails/tasks/engine.rake +69 -0
- data/lib/rails/tasks/framework.rake +4 -21
- data/lib/rails/tasks/misc.rake +1 -1
- data/lib/rails/tasks/routes.rake +2 -1
- data/lib/rails/test_help.rb +17 -1
- data/lib/rails/test_unit/railtie.rb +1 -1
- data/lib/rails/test_unit/testing.rake +8 -3
- data/lib/rails/version.rb +3 -3
- metadata +128 -100
- checksums.yaml +0 -7
- data/lib/rails/application/configurable.rb +0 -19
- data/lib/rails/console/sandbox.rb +0 -6
- data/lib/rails/deprecation.rb +0 -41
- data/lib/rails/engine/configurable.rb +0 -25
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +0 -62
- data/lib/rails/generators/rails/app/templates/public/javascripts/application.js +0 -2
- data/lib/rails/generators/rails/app/templates/public/javascripts/controls.js +0 -965
- data/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js +0 -974
- data/lib/rails/generators/rails/app/templates/public/javascripts/effects.js +0 -1123
- data/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js +0 -6001
- data/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +0 -202
- data/lib/rails/generators/rails/stylesheets/USAGE +0 -5
- data/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb +0 -9
- data/lib/rails/info_routes.rb +0 -3
@@ -12,6 +12,8 @@
|
|
12
12
|
|
13
13
|
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shCore.css" />
|
14
14
|
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shThemeRailsGuides.css" />
|
15
|
+
|
16
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/fixes.css" />
|
15
17
|
</head>
|
16
18
|
<body class="guide">
|
17
19
|
<% if @edge %>
|
@@ -106,14 +108,14 @@
|
|
106
108
|
<div class="wrapper">
|
107
109
|
<div id="mainCol">
|
108
110
|
<%= yield.html_safe %>
|
109
|
-
|
111
|
+
|
110
112
|
<h3>Feedback</h3>
|
111
113
|
<p>
|
112
|
-
You're encouraged to help
|
114
|
+
You're encouraged to help improve the quality of this guide.
|
113
115
|
</p>
|
114
116
|
<p>
|
115
117
|
If you see any typos or factual errors you are confident to
|
116
|
-
patch please clone <%= link_to 'docrails', 'https://github.com/lifo/docrails' %>
|
118
|
+
patch, please clone <%= link_to 'docrails', 'https://github.com/lifo/docrails' %>
|
117
119
|
and push the change yourself. That branch of Rails has public write access.
|
118
120
|
Commits are still reviewed, but that happens after you've submitted your
|
119
121
|
contribution. <%= link_to 'docrails', 'https://github.com/lifo/docrails' %> is
|
@@ -123,10 +125,7 @@
|
|
123
125
|
You may also find incomplete content, or stuff that is not up to date.
|
124
126
|
Please do add any missing documentation for master. Check the
|
125
127
|
<%= link_to 'Ruby on Rails Guides Guidelines', 'ruby_on_rails_guides_guidelines.html' %>
|
126
|
-
|
127
|
-
</p>
|
128
|
-
<p>
|
129
|
-
Issues may also be reported <%= link_to 'in Github', 'https://github.com/lifo/docrails/issues' %>.
|
128
|
+
for style and conventions.
|
130
129
|
</p>
|
131
130
|
<p>And last but not least, any kind of discussion regarding Ruby on Rails
|
132
131
|
documentation is very welcome in the <%= link_to 'rubyonrails-docs mailing list', 'http://groups.google.com/group/rubyonrails-docs' %>.
|
@@ -27,7 +27,7 @@ I'll cover each of these methods in turn. But first, a few words about the very
|
|
27
27
|
|
28
28
|
h4. Rendering by Default: Convention Over Configuration in Action
|
29
29
|
|
30
|
-
You've heard that Rails promotes "convention over configuration.
|
30
|
+
You've heard that Rails promotes "convention over configuration". Default rendering is an excellent example of this. By default, controllers in Rails automatically render views with names that correspond to valid routes. For example, if you have this code in your +BooksController+ class:
|
31
31
|
|
32
32
|
<ruby>
|
33
33
|
class BooksController < ApplicationController
|
@@ -46,7 +46,7 @@ And you have a view file +app/views/books/index.html.erb+:
|
|
46
46
|
<h1>Books are coming soon!</h1>
|
47
47
|
</ruby>
|
48
48
|
|
49
|
-
Rails will automatically render +app/views/books/index.html.erb+ when you navigate to +/books+ and you will see
|
49
|
+
Rails will automatically render +app/views/books/index.html.erb+ when you navigate to +/books+ and you will see "Books are coming soon!" on your screen.
|
50
50
|
|
51
51
|
However a coming soon screen is only minimally useful, so you will soon create your +Book+ model and add the index action to +BooksController+:
|
52
52
|
|
@@ -58,9 +58,9 @@ class BooksController < ApplicationController
|
|
58
58
|
end
|
59
59
|
</ruby>
|
60
60
|
|
61
|
-
Note that
|
61
|
+
Note that we don't have explicit render at the end of the index action in accordance with "convention over configuration" principle. The rule is that if you do not explicitly render something at the end of a controller action, Rails will automatically look for the +action_name.html.erb+ template in the controller's view path and render it. So in this case, Rails will render the +app/views/books/index.html.erb+ file.
|
62
62
|
|
63
|
-
|
63
|
+
If we want to display the properties of all the books in our view, we can do so with an ERB template like this:
|
64
64
|
|
65
65
|
<ruby>
|
66
66
|
<h1>Listing Books</h1>
|
@@ -90,7 +90,7 @@ So in our view, we want to display the properties of all the books, we could do
|
|
90
90
|
<%= link_to 'New book', new_book_path %>
|
91
91
|
</ruby>
|
92
92
|
|
93
|
-
NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. In Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby),
|
93
|
+
NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. In Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby), and +.builder+ for Builder (XML generator).
|
94
94
|
|
95
95
|
h4. Using +render+
|
96
96
|
|
@@ -109,7 +109,7 @@ render :nothing => true
|
|
109
109
|
If you look at the response for this using cURL, you will see the following:
|
110
110
|
|
111
111
|
<shell>
|
112
|
-
|
112
|
+
$ curl -i 127.0.0.1:3000/books
|
113
113
|
HTTP/1.1 200 OK
|
114
114
|
Connection: close
|
115
115
|
Date: Sun, 24 Jan 2010 09:25:18 GMT
|
@@ -134,11 +134,10 @@ If you want to render the view that corresponds to a different action within the
|
|
134
134
|
<ruby>
|
135
135
|
def update
|
136
136
|
@book = Book.find(params[:id])
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
end
|
137
|
+
if @book.update_attributes(params[:book])
|
138
|
+
redirect_to(@book)
|
139
|
+
else
|
140
|
+
render "edit"
|
142
141
|
end
|
143
142
|
end
|
144
143
|
</ruby>
|
@@ -150,11 +149,10 @@ If you prefer, you can use a symbol instead of a string to specify the action to
|
|
150
149
|
<ruby>
|
151
150
|
def update
|
152
151
|
@book = Book.find(params[:id])
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
end
|
152
|
+
if @book.update_attributes(params[:book])
|
153
|
+
redirect_to(@book)
|
154
|
+
else
|
155
|
+
render :edit
|
158
156
|
end
|
159
157
|
end
|
160
158
|
</ruby>
|
@@ -164,11 +162,10 @@ To be explicit, you can use +render+ with the +:action+ option (though this is n
|
|
164
162
|
<ruby>
|
165
163
|
def update
|
166
164
|
@book = Book.find(params[:id])
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
end
|
165
|
+
if @book.update_attributes(params[:book])
|
166
|
+
redirect_to(@book)
|
167
|
+
else
|
168
|
+
render :action => "edit"
|
172
169
|
end
|
173
170
|
end
|
174
171
|
</ruby>
|
@@ -208,13 +205,13 @@ The +:file+ option takes an absolute file-system path. Of course, you need to ha
|
|
208
205
|
|
209
206
|
NOTE: By default, the file is rendered without using the current layout. If you want Rails to put the file into the current layout, you need to add the +:layout => true+ option.
|
210
207
|
|
211
|
-
TIP: If you're running on Microsoft Windows, you should use the +:file+ option to render a file, because Windows filenames do not have the same format as Unix filenames.
|
208
|
+
TIP: If you're running Rails on Microsoft Windows, you should use the +:file+ option to render a file, because Windows filenames do not have the same format as Unix filenames.
|
212
209
|
|
213
210
|
h5. Wrapping it up
|
214
211
|
|
215
|
-
The above three
|
212
|
+
The above three ways of rendering (rendering another template within the controller, rendering a template within another controller and rendering an arbitrary file on the file system) are actually variants of the same action.
|
216
213
|
|
217
|
-
In fact, in the BooksController
|
214
|
+
In fact, in the BooksController class, inside of the update action where we want to render the edit template if the book does not update successfully, all of the following render calls would all render the +edit.html.erb+ template in the +views/books+ directory:
|
218
215
|
|
219
216
|
<ruby>
|
220
217
|
render :edit
|
@@ -241,30 +238,18 @@ The +render+ method can do without a view completely, if you're willing to use t
|
|
241
238
|
|
242
239
|
<ruby>
|
243
240
|
render :inline =>
|
244
|
-
"<% products.each do |p| %><p><%= p.name
|
241
|
+
"<% products.each do |p| %><p><%= p.name %></p><% end %>"
|
245
242
|
</ruby>
|
246
243
|
|
247
244
|
WARNING: There is seldom any good reason to use this option. Mixing ERB into your controllers defeats the MVC orientation of Rails and will make it harder for other developers to follow the logic of your project. Use a separate erb view instead.
|
248
245
|
|
249
|
-
By default, inline rendering uses
|
246
|
+
By default, inline rendering uses ERB. You can force it to use Builder instead with the +:type+ option:
|
250
247
|
|
251
248
|
<ruby>
|
252
249
|
render :inline =>
|
253
250
|
"xml.p {'Horrid coding practice!'}", :type => :builder
|
254
251
|
</ruby>
|
255
252
|
|
256
|
-
h5. Using +render+ with +:update+
|
257
|
-
|
258
|
-
You can also render javascript-based page updates inline using the +:update+ option to +render+:
|
259
|
-
|
260
|
-
<ruby>
|
261
|
-
render :update do |page|
|
262
|
-
page.replace_html 'warning', "Invalid options supplied"
|
263
|
-
end
|
264
|
-
</ruby>
|
265
|
-
|
266
|
-
WARNING: Placing javascript updates in your controller may seem to streamline small updates, but it defeats the MVC orientation of Rails and will make it harder for other developers to follow the logic of your project. We recommend using a separate rjs template instead, no matter how small the update.
|
267
|
-
|
268
253
|
h5. Rendering Text
|
269
254
|
|
270
255
|
You can send plain text - with no markup at all - back to the browser by using the +:text+ option to +render+:
|
@@ -275,11 +260,11 @@ render :text => "OK"
|
|
275
260
|
|
276
261
|
TIP: Rendering pure text is most useful when you're responding to AJAX or web service requests that are expecting something other than proper HTML.
|
277
262
|
|
278
|
-
NOTE: By default, if you use the +:text+ option the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the +:layout => true+ option.
|
263
|
+
NOTE: By default, if you use the +:text+ option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the +:layout => true+ option.
|
279
264
|
|
280
265
|
h5. Rendering JSON
|
281
266
|
|
282
|
-
JSON is a
|
267
|
+
JSON is a JavaScript data format used by many AJAX libraries. Rails has built-in support for converting objects to JSON and rendering that JSON back to the browser:
|
283
268
|
|
284
269
|
<ruby>
|
285
270
|
render :json => @product
|
@@ -299,7 +284,7 @@ TIP: You don't need to call +to_xml+ on the object that you want to render. If y
|
|
299
284
|
|
300
285
|
h5. Rendering Vanilla JavaScript
|
301
286
|
|
302
|
-
Rails can render vanilla JavaScript
|
287
|
+
Rails can render vanilla JavaScript:
|
303
288
|
|
304
289
|
<ruby>
|
305
290
|
render :js => "alert('Hello Rails');"
|
@@ -342,7 +327,7 @@ render :layout => false
|
|
342
327
|
|
343
328
|
h6. The +:status+ Option
|
344
329
|
|
345
|
-
Rails will automatically generate a response with the correct
|
330
|
+
Rails will automatically generate a response with the correct HTTP status code (in most cases, this is +200 OK+). You can use the +:status+ option to change this:
|
346
331
|
|
347
332
|
<ruby>
|
348
333
|
render :status => 500
|
@@ -409,7 +394,7 @@ end
|
|
409
394
|
|
410
395
|
Now, if the current user is a special user, they'll get a special layout when viewing a product. You can even use an inline method to determine the layout:
|
411
396
|
|
412
|
-
You can also decide the layout by passing a Proc object, the block you give the Proc will be given the +controller+ instance, so you can make decisions based on the current request.
|
397
|
+
You can also decide the layout by passing a Proc object, the block you give the Proc will be given the +controller+ instance, so you can make decisions based on the current request. For example:
|
413
398
|
|
414
399
|
<ruby>
|
415
400
|
class ProductsController < ApplicationController
|
@@ -498,7 +483,7 @@ def show
|
|
498
483
|
end
|
499
484
|
</ruby>
|
500
485
|
|
501
|
-
If +@book.special?+ evaluates to +true+, Rails will start the rendering process to dump the +@book+ variable into the +special_show+ view. But this will _not_ stop the rest of the code in the +show+ action from running, and when Rails hits the end of the action, it will start to render the +
|
486
|
+
If +@book.special?+ evaluates to +true+, Rails will start the rendering process to dump the +@book+ variable into the +special_show+ view. But this will _not_ stop the rest of the code in the +show+ action from running, and when Rails hits the end of the action, it will start to render the +regular_show+ view - and throw an error. The solution is simple: make sure that you have only one call to +render+ or +redirect+ in a single code path. One thing that can help is +and return+. Here's a patched version of the method:
|
502
487
|
|
503
488
|
<ruby>
|
504
489
|
def show
|
@@ -568,7 +553,7 @@ def show
|
|
568
553
|
end
|
569
554
|
</ruby>
|
570
555
|
|
571
|
-
With the code in this form, there will
|
556
|
+
With the code in this form, there will likely be a problem if the +@book+ variable is +nil+. Remember, a +render :action+ doesn't run any code in the target action, so nothing will set up the +@books+ variable that the +index+ view is presumably depending on. One way to fix this is to redirect instead of rendering:
|
572
557
|
|
573
558
|
<ruby>
|
574
559
|
def index
|
@@ -585,9 +570,9 @@ end
|
|
585
570
|
|
586
571
|
With this code, the browser will make a fresh request for the index page, the code in the +index+ method will run, and all will be well.
|
587
572
|
|
588
|
-
The only downside to this code, is that it requires a round trip to the browser, the browser requested the show action with +/books/1+ and the controller finds that there are no books, so the controller sends out a
|
573
|
+
The only downside to this code, is that it requires a round trip to the browser, the browser requested the show action with +/books/1+ and the controller finds that there are no books, so the controller sends out a 302 redirect response to the browser telling it to go to +/books/+, the browser complies and sends a new request back to the controller asking now for the +index+ action, the controller then gets all the books in the database and renders the index template, sending it back down to the browser which then shows it on your screen.
|
589
574
|
|
590
|
-
While in a small app, this added latency might not be a problem, it is something to think about when speed of response is of the essence.
|
575
|
+
While in a small app, this added latency might not be a problem, it is something to think about when speed of response is of the essence. One way to handle this double request (though a contrived example) could be:
|
591
576
|
|
592
577
|
<ruby>
|
593
578
|
def index
|
@@ -603,7 +588,7 @@ def show
|
|
603
588
|
end
|
604
589
|
</ruby>
|
605
590
|
|
606
|
-
Which would detect that there are no books populate the +@books+ instance variable with all the books in the database and then directly render the +index.html.erb+ template returning it to the browser with a flash alert message telling the user what happened.
|
591
|
+
Which would detect that there are no books, populate the +@books+ instance variable with all the books in the database and then directly render the +index.html.erb+ template returning it to the browser with a flash alert message telling the user what happened.
|
607
592
|
|
608
593
|
h4. Using +head+ To Build Header-Only Responses
|
609
594
|
|
@@ -684,7 +669,7 @@ There are three tag options available for +auto_discovery_link_tag+:
|
|
684
669
|
* +:type+ specifies an explicit MIME type. Rails will generate an appropriate MIME type automatically.
|
685
670
|
* +:title+ specifies the title of the link
|
686
671
|
|
687
|
-
h5. Linking to
|
672
|
+
h5. Linking to JavaScript Files with +javascript_include_tag+
|
688
673
|
|
689
674
|
The +javascript_include_tag+ helper returns an HTML +script+ tag for each source provided. Rails looks in +public/javascripts+ for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include +public/javascripts/main.js+:
|
690
675
|
|
@@ -710,25 +695,35 @@ To include +http://example.com/main.js+:
|
|
710
695
|
<%= javascript_include_tag "http://example.com/main.js" %>
|
711
696
|
</erb>
|
712
697
|
|
713
|
-
|
698
|
+
If the application does not use the asset pipeline, the +:defaults+ option loads jQuery by default:
|
714
699
|
|
715
700
|
<erb>
|
716
701
|
<%= javascript_include_tag :defaults %>
|
717
702
|
</erb>
|
718
703
|
|
719
|
-
|
704
|
+
And you can in any case override the expansion in <tt>config/application.rb</tt>:
|
705
|
+
|
706
|
+
<ruby>
|
707
|
+
config.action_view.javascript_expansions[:defaults] = %w(foo.js bar.js)
|
708
|
+
</ruby>
|
709
|
+
|
710
|
+
When using <tt>:defaults</tt>, if an <tt>application.js</tt> file exists in <tt>public/javascripts</tt> it will be included as well at then end.
|
711
|
+
|
712
|
+
Also, the +:all+ option loads every JavaScript file in +public/javascripts+:
|
720
713
|
|
721
714
|
<erb>
|
722
715
|
<%= javascript_include_tag :all %>
|
723
716
|
</erb>
|
724
717
|
|
718
|
+
Note that your defaults of choice will be included first, so they will be available to all subsequently included files.
|
719
|
+
|
725
720
|
You can supply the +:recursive+ option to load files in subfolders of +public/javascripts+ as well:
|
726
721
|
|
727
722
|
<erb>
|
728
723
|
<%= javascript_include_tag :all, :recursive => true %>
|
729
724
|
</erb>
|
730
725
|
|
731
|
-
If you're loading multiple
|
726
|
+
If you're loading multiple JavaScript files, you can create a better user experience by combining multiple files into a single download. To make this happen in production, specify +:cache => true+ in your +javascript_include_tag+:
|
732
727
|
|
733
728
|
<erb>
|
734
729
|
<%= javascript_include_tag "main", "columns", :cache => true %>
|
@@ -804,7 +799,9 @@ You can even use dynamic paths such as +cache/#{current_site}/main/display+.
|
|
804
799
|
|
805
800
|
h5. Linking to Images with +image_tag+
|
806
801
|
|
807
|
-
The +image_tag+ helper builds an HTML +<img />+ tag to the specified file. By default, files are loaded from +public/images
|
802
|
+
The +image_tag+ helper builds an HTML +<img />+ tag to the specified file. By default, files are loaded from +public/images+.
|
803
|
+
|
804
|
+
WARNING: Note that you must specify the extension of the image. Previous versions of Rails would allow you to just use the image name and would append +.png+ if no extension was given but Rails 3.0 does not.
|
808
805
|
|
809
806
|
<erb>
|
810
807
|
<%= image_tag "header.png" %>
|
@@ -841,7 +838,7 @@ You can also specify a special size tag, in the format "{width}x{height}":
|
|
841
838
|
<%= image_tag "home.gif", :size => "50x20" %>
|
842
839
|
</erb>
|
843
840
|
|
844
|
-
In addition to the above special tags, you can supply a final hash of standard HTML options, such as +:class
|
841
|
+
In addition to the above special tags, you can supply a final hash of standard HTML options, such as +:class+, +:id+ or +:name+:
|
845
842
|
|
846
843
|
<erb>
|
847
844
|
<%= image_tag "home.gif", :alt => "Go Home",
|
@@ -863,7 +860,7 @@ Produces
|
|
863
860
|
<video src="/videos/movie.ogg" />
|
864
861
|
</erb>
|
865
862
|
|
866
|
-
Like an +image_tag+ you can supply a path, either absolute, or relative to the +public/videos+ directory.
|
863
|
+
Like an +image_tag+ you can supply a path, either absolute, or relative to the +public/videos+ directory. Additionally you can specify the +:size => "#{width}x#{height}"+ option just like an +image_tag+. Video tags can also have any of the HTML options specified at the end (+id+, +class+ et al).
|
867
864
|
|
868
865
|
The video tag also supports all of the +<video>+ HTML options through the HTML options hash, including:
|
869
866
|
|
@@ -961,7 +958,7 @@ The result of rendering this page into the supplied layout would be this HTML:
|
|
961
958
|
</html>
|
962
959
|
</erb>
|
963
960
|
|
964
|
-
The +content_for+ method is very helpful when your layout contains distinct regions such as sidebars and footers that should get their own blocks of content inserted. It's also useful for inserting tags that load page-specific
|
961
|
+
The +content_for+ method is very helpful when your layout contains distinct regions such as sidebars and footers that should get their own blocks of content inserted. It's also useful for inserting tags that load page-specific JavaScript or css files into the header of an otherwise generic layout.
|
965
962
|
|
966
963
|
h4. Using Partials
|
967
964
|
|
@@ -1007,11 +1004,13 @@ h5. Partial Layouts
|
|
1007
1004
|
A partial can use its own layout file, just as a view can use a layout. For example, you might call a partial like this:
|
1008
1005
|
|
1009
1006
|
<erb>
|
1010
|
-
<%= render "link_area", :layout => "graybar" %>
|
1007
|
+
<%= render :partial => "link_area", :layout => "graybar" %>
|
1011
1008
|
</erb>
|
1012
1009
|
|
1013
1010
|
This would look for a partial named +_link_area.html.erb+ and render it using the layout +_graybar.html.erb+. Note that layouts for partials follow the same leading-underscore naming as regular partials, and are placed in the same folder with the partial that they belong to (not in the master +layouts+ folder).
|
1014
1011
|
|
1012
|
+
Also note that explicitly specifying +:partial+ is required when passing additional options such as +:layout+.
|
1013
|
+
|
1015
1014
|
h5. Passing Local Variables
|
1016
1015
|
|
1017
1016
|
You can also pass local variables into partials, making them even more powerful and flexible. For example, you can use this technique to reduce duplication between new and edit pages, while still keeping a bit of distinct content:
|
@@ -1134,7 +1133,7 @@ You can also pass in arbitrary local variables to any partial you are rendering
|
|
1134
1133
|
|
1135
1134
|
Would render a partial +_products.html.erb+ once for each instance of +product+ in the +@products+ instance variable passing the instance to the partial as a local variable called +item+ and to each partial, make the local variable +title+ available with the value +Products Page+.
|
1136
1135
|
|
1137
|
-
TIP: Rails also makes a counter variable available within a partial called by the collection, named after the member of the collection followed by +_counter+. For example, if you're rendering +@products+, within the partial you can refer to +product_counter+ to tell you how many times the partial has been rendered.
|
1136
|
+
TIP: Rails also makes a counter variable available within a partial called by the collection, named after the member of the collection followed by +_counter+. For example, if you're rendering +@products+, within the partial you can refer to +product_counter+ to tell you how many times the partial has been rendered. This does not work in conjunction with the +:as => :value+ option.
|
1138
1137
|
|
1139
1138
|
You can also specify a second partial to be rendered between instances of the main partial by using the +:spacer_template+ option:
|
1140
1139
|
|
@@ -1182,12 +1181,12 @@ On pages generated by +NewsController+, you want to hide the top menu and add a
|
|
1182
1181
|
<div id="right_menu">Right menu items here</div>
|
1183
1182
|
<%= yield(:news_content) or yield %>
|
1184
1183
|
<% end %>
|
1185
|
-
<%= render :
|
1184
|
+
<%= render :template => 'layouts/application' %>
|
1186
1185
|
</erb>
|
1187
1186
|
|
1188
1187
|
That's it. The News views will use the new layout, hiding the top menu and adding a new right menu inside the "content" div.
|
1189
1188
|
|
1190
|
-
There are several ways of getting similar results with different sub-templating schemes using this technique. Note that there is no limit in nesting levels. One can use the +ActionView::render+ method via +render :
|
1189
|
+
There are several ways of getting similar results with different sub-templating schemes using this technique. Note that there is no limit in nesting levels. One can use the +ActionView::render+ method via +render :template => 'layouts/news'+ to base a new layout on the News layout. If you are sure you will not subtemplate the +News+ layout, you can replace the +yield(:news_content) or yield+ with simply +yield+.
|
1191
1190
|
|
1192
1191
|
h3. Changelog
|
1193
1192
|
|
@@ -21,7 +21,7 @@ Before I dive into the details of a migration, here are a few examples of the so
|
|
21
21
|
|
22
22
|
<ruby>
|
23
23
|
class CreateProducts < ActiveRecord::Migration
|
24
|
-
def
|
24
|
+
def up
|
25
25
|
create_table :products do |t|
|
26
26
|
t.string :name
|
27
27
|
t.text :description
|
@@ -30,7 +30,7 @@ class CreateProducts < ActiveRecord::Migration
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def down
|
34
34
|
drop_table :products
|
35
35
|
end
|
36
36
|
end
|
@@ -42,14 +42,14 @@ Migrations are not limited to changing the schema. You can also use them to fix
|
|
42
42
|
|
43
43
|
<ruby>
|
44
44
|
class AddReceiveNewsletterToUsers < ActiveRecord::Migration
|
45
|
-
def
|
45
|
+
def up
|
46
46
|
change_table :users do |t|
|
47
47
|
t.boolean :receive_newsletter, :default => false
|
48
48
|
end
|
49
49
|
User.update_all ["receive_newsletter = ?", true]
|
50
50
|
end
|
51
51
|
|
52
|
-
def
|
52
|
+
def down
|
53
53
|
remove_column :users, :receive_newsletter
|
54
54
|
end
|
55
55
|
end
|
@@ -58,6 +58,21 @@ end
|
|
58
58
|
This migration adds a +receive_newsletter+ column to the +users+ table. We want it to default to +false+ for new users, but existing users are considered
|
59
59
|
to have already opted in, so we use the User model to set the flag to +true+ for existing users.
|
60
60
|
|
61
|
+
Rails 3.1 makes migrations smarter by providing a new <tt>change</tt> method. This method is preferred for writing constructive migrations (adding columns or tables). The migration knows how to migrate your database and reverse it when the migration is rolled back without the need to write a separate +down+ method.
|
62
|
+
|
63
|
+
<ruby>
|
64
|
+
class CreateProducts < ActiveRecord::Migration
|
65
|
+
def change
|
66
|
+
create_table :products do |t|
|
67
|
+
t.string :name
|
68
|
+
t.text :description
|
69
|
+
|
70
|
+
t.timestamps
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
</ruby>
|
75
|
+
|
61
76
|
NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations.
|
62
77
|
|
63
78
|
h4. Migrations are Classes
|
@@ -109,14 +124,14 @@ h4. Creating a Model
|
|
109
124
|
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
|
110
125
|
|
111
126
|
<shell>
|
112
|
-
rails generate model Product name:string description:text
|
127
|
+
$ rails generate model Product name:string description:text
|
113
128
|
</shell>
|
114
129
|
|
115
130
|
will create a migration that looks like this
|
116
131
|
|
117
132
|
<ruby>
|
118
133
|
class CreateProducts < ActiveRecord::Migration
|
119
|
-
def
|
134
|
+
def change
|
120
135
|
create_table :products do |t|
|
121
136
|
t.string :name
|
122
137
|
t.text :description
|
@@ -124,10 +139,6 @@ class CreateProducts < ActiveRecord::Migration
|
|
124
139
|
t.timestamps
|
125
140
|
end
|
126
141
|
end
|
127
|
-
|
128
|
-
def self.down
|
129
|
-
drop_table :products
|
130
|
-
end
|
131
142
|
end
|
132
143
|
</ruby>
|
133
144
|
|
@@ -139,17 +150,14 @@ h4. Creating a Standalone Migration
|
|
139
150
|
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:
|
140
151
|
|
141
152
|
<shell>
|
142
|
-
rails generate migration AddPartNumberToProducts
|
153
|
+
$ rails generate migration AddPartNumberToProducts
|
143
154
|
</shell>
|
144
155
|
|
145
156
|
This will create an empty but appropriately named migration:
|
146
157
|
|
147
158
|
<ruby>
|
148
159
|
class AddPartNumberToProducts < ActiveRecord::Migration
|
149
|
-
def
|
150
|
-
end
|
151
|
-
|
152
|
-
def self.down
|
160
|
+
def change
|
153
161
|
end
|
154
162
|
end
|
155
163
|
</ruby>
|
@@ -157,38 +165,34 @@ end
|
|
157
165
|
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.
|
158
166
|
|
159
167
|
<shell>
|
160
|
-
rails generate migration AddPartNumberToProducts part_number:string
|
168
|
+
$ rails generate migration AddPartNumberToProducts part_number:string
|
161
169
|
</shell>
|
162
170
|
|
163
171
|
will generate
|
164
172
|
|
165
173
|
<ruby>
|
166
174
|
class AddPartNumberToProducts < ActiveRecord::Migration
|
167
|
-
def
|
175
|
+
def change
|
168
176
|
add_column :products, :part_number, :string
|
169
177
|
end
|
170
|
-
|
171
|
-
def self.down
|
172
|
-
remove_column :products, :part_number
|
173
|
-
end
|
174
178
|
end
|
175
179
|
</ruby>
|
176
180
|
|
177
181
|
Similarly,
|
178
182
|
|
179
183
|
<shell>
|
180
|
-
rails generate migration RemovePartNumberFromProducts part_number:string
|
184
|
+
$ rails generate migration RemovePartNumberFromProducts part_number:string
|
181
185
|
</shell>
|
182
186
|
|
183
187
|
generates
|
184
188
|
|
185
189
|
<ruby>
|
186
190
|
class RemovePartNumberFromProducts < ActiveRecord::Migration
|
187
|
-
def
|
191
|
+
def up
|
188
192
|
remove_column :products, :part_number
|
189
193
|
end
|
190
194
|
|
191
|
-
def
|
195
|
+
def down
|
192
196
|
add_column :products, :part_number, :string
|
193
197
|
end
|
194
198
|
end
|
@@ -197,27 +201,24 @@ end
|
|
197
201
|
You are not limited to one magically generated column, for example
|
198
202
|
|
199
203
|
<shell>
|
200
|
-
rails generate migration AddDetailsToProducts part_number:string price:decimal
|
204
|
+
$ rails generate migration AddDetailsToProducts part_number:string price:decimal
|
201
205
|
</shell>
|
202
206
|
|
203
207
|
generates
|
204
208
|
|
205
209
|
<ruby>
|
206
210
|
class AddDetailsToProducts < ActiveRecord::Migration
|
207
|
-
def
|
211
|
+
def change
|
208
212
|
add_column :products, :part_number, :string
|
209
213
|
add_column :products, :price, :decimal
|
210
214
|
end
|
211
|
-
|
212
|
-
def self.down
|
213
|
-
remove_column :products, :price
|
214
|
-
remove_column :products, :part_number
|
215
|
-
end
|
216
215
|
end
|
217
216
|
</ruby>
|
218
217
|
|
219
218
|
As always, what has been generated for you is just a starting point. You can add or remove from it as you see fit.
|
220
219
|
|
220
|
+
NOTE: The generated migration file for destructive migrations will still be old-style using the +up+ and +down+ methods. This is because Rails doesn't know the original data types defined when you made the original changes.
|
221
|
+
|
221
222
|
h3. Writing a Migration
|
222
223
|
|
223
224
|
Once you have created your migration using one of the generators it's time to get to work!
|
@@ -284,7 +285,7 @@ change_table :products do |t|
|
|
284
285
|
t.rename :upccode, :upc_code
|
285
286
|
end
|
286
287
|
</ruby>
|
287
|
-
removes the +description+ and +name+ columns, creates a +part_number+ column and adds an index on it. Finally it renames the +upccode+ column.
|
288
|
+
removes the +description+ and +name+ columns, creates a +part_number+ column and adds an index on it. Finally it renames the +upccode+ column. This is the same as doing
|
288
289
|
|
289
290
|
<ruby>
|
290
291
|
remove_column :products, :description
|
@@ -335,7 +336,22 @@ NOTE: The +references+ helper does not actually create foreign key constraints f
|
|
335
336
|
|
336
337
|
If the helpers provided by Active Record aren't enough you can use the +execute+ function to execute arbitrary SQL.
|
337
338
|
|
338
|
-
For more details and examples of individual methods check the API documentation, in particular the documentation for "<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html (which provides the methods available in the +up+ and +down+ methods),
|
339
|
+
For more details and examples of individual methods check the API documentation, in particular the documentation for "<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html (which provides the methods available in the +up+ and +down+ methods), "<tt>ActiveRecord::ConnectionAdapters::TableDefinition</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html (which provides the methods available on the object yielded by +create_table+) and "<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html (which provides the methods available on the object yielded by +change_table+).
|
340
|
+
|
341
|
+
h4. Writing Your +change+ Method
|
342
|
+
|
343
|
+
The +change+ method removes the need to write both +up+ and +down+ methods in those cases that Rails know how to revert the changes automatically. Currently, the +change+ method supports only these migration definitions:
|
344
|
+
|
345
|
+
* +add_column+
|
346
|
+
* +add_index+
|
347
|
+
* +add_timestamp+
|
348
|
+
* +create_table+
|
349
|
+
* +remove_timestamps+
|
350
|
+
* +rename_column+
|
351
|
+
* +rename_index+
|
352
|
+
* +rename_table+
|
353
|
+
|
354
|
+
If you're going to use other methods, you'll have to write the +up+ and +down+ methods normally.
|
339
355
|
|
340
356
|
h4. Writing Your +down+ Method
|
341
357
|
|
@@ -344,7 +360,7 @@ The +down+ method of your migration should revert the transformations done by th
|
|
344
360
|
<ruby>
|
345
361
|
class ExampleMigration < ActiveRecord::Migration
|
346
362
|
|
347
|
-
def
|
363
|
+
def up
|
348
364
|
create_table :products do |t|
|
349
365
|
t.references :category
|
350
366
|
end
|
@@ -361,7 +377,7 @@ class ExampleMigration < ActiveRecord::Migration
|
|
361
377
|
rename_column :users, :email, :email_address
|
362
378
|
end
|
363
379
|
|
364
|
-
def
|
380
|
+
def down
|
365
381
|
rename_column :users, :email_address, :email
|
366
382
|
remove_column :users, :home_page_url
|
367
383
|
execute "ALTER TABLE products DROP FOREIGN KEY fk_products_categories"
|
@@ -369,9 +385,8 @@ class ExampleMigration < ActiveRecord::Migration
|
|
369
385
|
end
|
370
386
|
end
|
371
387
|
</ruby>
|
372
|
-
Sometimes your migration will do something which is just plain irreversible, for example it might destroy some data. In cases like those when you can't reverse the migration you can raise +IrreversibleMigration+ from your +down+ method. If someone tries to revert your migration an error message will be
|
373
|
-
displayed saying that it can't be done.
|
374
388
|
|
389
|
+
Sometimes your migration will do something which is just plain irreversible, for example it might destroy some data. In cases like those when you can't reverse the migration you can raise +IrreversibleMigration+ from your +down+ method. If someone tries to revert your migration an error message will be displayed saying that it can't be done.
|
375
390
|
|
376
391
|
h3. Running Migrations
|
377
392
|
|
@@ -383,7 +398,7 @@ If you specify a target version, Active Record will run the required migrations
|
|
383
398
|
version is the numerical prefix on the migration's filename. For example to migrate to version 20080906120000 run
|
384
399
|
|
385
400
|
<shell>
|
386
|
-
rake db:migrate VERSION=20080906120000
|
401
|
+
$ rake db:migrate VERSION=20080906120000
|
387
402
|
</shell>
|
388
403
|
|
389
404
|
If this is greater than the current version (i.e. it is migrating upwards) this will run the +up+ method on all migrations up to and including 20080906120000, if migrating downwards this will run the +down+ method on all the migrations down to, but not including, 20080906120000.
|
@@ -393,13 +408,13 @@ h4. Rolling Back
|
|
393
408
|
A common task is to rollback the last migration, for example if you made a mistake in it and wish to correct it. Rather than tracking down the version number associated with the previous migration you can run
|
394
409
|
|
395
410
|
<shell>
|
396
|
-
rake db:rollback
|
411
|
+
$ rake db:rollback
|
397
412
|
</shell>
|
398
413
|
|
399
414
|
This will run the +down+ method from the latest migration. If you need to undo several migrations you can provide a +STEP+ parameter:
|
400
415
|
|
401
416
|
<shell>
|
402
|
-
rake db:rollback STEP=3
|
417
|
+
$ rake db:rollback STEP=3
|
403
418
|
</shell>
|
404
419
|
|
405
420
|
will run the +down+ method from the last 3 migrations.
|
@@ -407,7 +422,7 @@ will run the +down+ method from the last 3 migrations.
|
|
407
422
|
The +db:migrate:redo+ task is a shortcut for doing a rollback and then migrating back up again. As with the +db:rollback+ task you can use the +STEP+ parameter if you need to go more than one version back, for example
|
408
423
|
|
409
424
|
<shell>
|
410
|
-
rake db:migrate:redo STEP=3
|
425
|
+
$ rake db:migrate:redo STEP=3
|
411
426
|
</shell>
|
412
427
|
|
413
428
|
Neither of these Rake tasks do anything you could not do with +db:migrate+, they are simply more convenient since you do not need to explicitly specify the version to migrate to.
|
@@ -421,7 +436,7 @@ h4. Being Specific
|
|
421
436
|
If you need to run a specific migration up or down the +db:migrate:up+ and +db:migrate:down+ tasks will do that. Just specify the appropriate version and the corresponding migration will have its +up+ or +down+ method invoked, for example
|
422
437
|
|
423
438
|
<shell>
|
424
|
-
rake db:migrate:up VERSION=20080906120000
|
439
|
+
$ rake db:migrate:up VERSION=20080906120000
|
425
440
|
</shell>
|
426
441
|
|
427
442
|
will run the +up+ method from the 20080906120000 migration. These tasks check whether the migration has already run, so for example +db:migrate:up VERSION=20080906120000+ will do nothing if Active Record believes that 20080906120000 has already been run.
|
@@ -449,7 +464,7 @@ For example, this migration
|
|
449
464
|
|
450
465
|
<ruby>
|
451
466
|
class CreateProducts < ActiveRecord::Migration
|
452
|
-
def
|
467
|
+
def change
|
453
468
|
suppress_messages do
|
454
469
|
create_table :products do |t|
|
455
470
|
t.string :name
|
@@ -465,10 +480,6 @@ class CreateProducts < ActiveRecord::Migration
|
|
465
480
|
250
|
466
481
|
end
|
467
482
|
end
|
468
|
-
|
469
|
-
def self.down
|
470
|
-
drop_table :products
|
471
|
-
end
|
472
483
|
end
|
473
484
|
</ruby>
|
474
485
|
|
@@ -499,11 +510,7 @@ class AddPartNumberToProducts < ActiveRecord::Migration
|
|
499
510
|
class Product < ActiveRecord::Base
|
500
511
|
end
|
501
512
|
|
502
|
-
def
|
503
|
-
...
|
504
|
-
end
|
505
|
-
|
506
|
-
def self.down
|
513
|
+
def change
|
507
514
|
...
|
508
515
|
end
|
509
516
|
end
|
@@ -519,15 +526,11 @@ class AddPartNumberToProducts < ActiveRecord::Migration
|
|
519
526
|
class Product < ActiveRecord::Base
|
520
527
|
end
|
521
528
|
|
522
|
-
def
|
529
|
+
def change
|
523
530
|
add_column :product, :part_number, :string
|
524
531
|
Product.reset_column_information
|
525
532
|
...
|
526
533
|
end
|
527
|
-
|
528
|
-
def self.down
|
529
|
-
...
|
530
|
-
end
|
531
534
|
end
|
532
535
|
</ruby>
|
533
536
|
|
@@ -584,11 +587,12 @@ h3. Active Record and Referential Integrity
|
|
584
587
|
|
585
588
|
The Active Record way claims that intelligence belongs in your models, not in the database. As such, features such as triggers or foreign key constraints, which push some of that intelligence back into the database, are not heavily used.
|
586
589
|
|
587
|
-
Validations such as +
|
590
|
+
Validations such as +validates :foreign_key, :uniqueness => true+ are one way in which models can enforce data integrity. The +:dependent+ option on associations allows models to automatically destroy child objects when the parent is destroyed. Like anything which operates at the application level these cannot guarantee referential integrity and so some people augment them with foreign key constraints.
|
588
591
|
|
589
|
-
Although Active Record does not provide any tools for working directly with such features, the +execute+ method can be used to execute arbitrary SQL. There are also a number of plugins such as "foreign_key_migrations":
|
592
|
+
Although Active Record does not provide any tools for working directly with such features, the +execute+ method can be used to execute arbitrary SQL. There are also a number of plugins such as "foreign_key_migrations":https://github.com/harukizaemon/redhillonrails/tree/master/foreign_key_migrations/ which add foreign key support to Active Record (including support for dumping foreign keys in +db/schema.rb+).
|
590
593
|
|
591
594
|
h3. Changelog
|
592
595
|
|
596
|
+
* April 26, 2011: change generated +up+ and +down+ methods to +change+ method, and describe detail about +change+ method by "Prem Sichanugrist":http://sikachu.com
|
593
597
|
* July 15, 2010: minor typos corrected by "Jaime Iniesta":http://jaimeiniesta.com
|
594
598
|
* September 14, 2008: initial version by "Frederick Cheung":credits.html#fcheung
|