railties 3.0.0.rc → 3.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +80 -75
- data/README.rdoc +1 -1
- data/guides/assets/stylesheets/main.css +14 -14
- data/guides/rails_guides.rb +20 -1
- data/guides/rails_guides/generator.rb +7 -7
- data/guides/source/2_3_release_notes.textile +5 -5
- data/guides/source/3_0_release_notes.textile +4 -3
- data/guides/source/action_controller_overview.textile +32 -17
- data/guides/source/action_view_overview.textile +44 -44
- data/guides/source/active_record_basics.textile +2 -2
- data/guides/source/active_record_querying.textile +7 -7
- data/guides/source/active_record_validations_callbacks.textile +20 -20
- data/guides/source/active_support_core_extensions.textile +370 -198
- data/guides/source/ajax_on_rails.textile +17 -17
- data/guides/source/api_documentation_guidelines.textile +3 -3
- data/guides/source/association_basics.textile +2 -2
- data/guides/source/caching_with_rails.textile +5 -5
- data/guides/source/command_line.textile +8 -8
- data/guides/source/configuring.textile +6 -6
- data/guides/source/contributing_to_rails.textile +14 -11
- data/guides/source/debugging_rails_applications.textile +8 -6
- data/guides/source/form_helpers.textile +1 -1
- data/guides/source/generators.textile +34 -30
- data/guides/source/getting_started.textile +13 -13
- data/guides/source/i18n.textile +12 -1
- data/guides/source/index.html.erb +4 -0
- data/guides/source/initialization.textile +67 -72
- data/guides/source/layout.html.erb +1 -0
- data/guides/source/layouts_and_rendering.textile +9 -9
- data/guides/source/nested_model_forms.textile +7 -7
- data/guides/source/plugins.textile +1 -1
- data/guides/source/rails_application_templates.textile +2 -2
- data/guides/source/routing.textile +27 -5
- data/guides/source/security.textile +6 -6
- data/guides/w3c_validator.rb +9 -9
- data/lib/rails/application.rb +1 -0
- data/lib/rails/application/configuration.rb +1 -1
- data/lib/rails/code_statistics.rb +4 -4
- data/lib/rails/commands.rb +1 -1
- data/lib/rails/commands/dbconsole.rb +1 -1
- data/lib/rails/commands/plugin.rb +1 -1
- data/lib/rails/commands/runner.rb +1 -1
- data/lib/rails/deprecation.rb +31 -52
- data/lib/rails/engine.rb +1 -1
- data/lib/rails/engine/configuration.rb +28 -1
- data/lib/rails/generators.rb +2 -2
- data/lib/rails/generators/actions.rb +3 -3
- data/lib/rails/generators/active_model.rb +3 -3
- data/lib/rails/generators/base.rb +1 -1
- data/lib/rails/generators/rails/app/app_generator.rb +9 -3
- data/lib/rails/generators/rails/app/templates/Gemfile +2 -2
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +4 -13
- 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 +4 -0
- data/lib/rails/generators/rails/app/templates/config/routes.rb +4 -4
- data/lib/rails/generators/rails/app/templates/public/index.html +0 -23
- data/lib/rails/generators/rails/app/templates/public/javascripts/effects.js +1 -1
- data/lib/rails/generators/rails/generator/USAGE +3 -2
- data/lib/rails/generators/rails/migration/USAGE +4 -4
- data/lib/rails/generators/rails/plugin/USAGE +1 -1
- data/lib/rails/generators/rails/resource/resource_generator.rb +2 -2
- data/lib/rails/generators/test_case.rb +1 -1
- data/lib/rails/info_controller.rb +1 -1
- data/lib/rails/plugin.rb +1 -1
- data/lib/rails/rack/log_tailer.rb +2 -5
- data/lib/rails/railtie.rb +22 -22
- data/lib/rails/script_rails_loader.rb +2 -2
- data/lib/rails/tasks/documentation.rake +5 -5
- data/lib/rails/tasks/framework.rake +1 -1
- data/lib/rails/tasks/routes.rake +23 -9
- data/lib/rails/test_unit/testing.rake +3 -2
- data/lib/rails/version.rb +1 -1
- metadata +10 -10
@@ -47,7 +47,7 @@ Let's start with the the probably most often used helper: +link_to_remote+, whic
|
|
47
47
|
The signature of +link_to_remote+ function is the same as that of the standard +link_to+ helper:
|
48
48
|
|
49
49
|
<ruby>
|
50
|
-
def link_to_remote(name, options = {}, html_options = nil)
|
50
|
+
def link_to_remote(name, options = {}, html_options = nil)
|
51
51
|
</ruby>
|
52
52
|
|
53
53
|
And here is a simple example of link_to_remote in action:
|
@@ -98,7 +98,7 @@ link_to_remote "Delete the item",
|
|
98
98
|
Note that if we wouldn't override the default behavior (POST), the above snippet would route to the create action rather than destroy.
|
99
99
|
|
100
100
|
** *JavaScript filters* You can customize the remote call further by wrapping it with some JavaScript code. Let's say in the previous example, when deleting a link, you'd like to ask for a confirmation by showing a simple modal text box to the user. This is a typical example what you can accomplish with these options - let's see them one by one:
|
101
|
-
*** +:confirm+ => +msg+ Pops up a JavaScript confirmation dialog, displaying +msg+. If the user chooses 'OK', the request is launched, otherwise canceled.
|
101
|
+
*** +:confirm+ => +msg+ Pops up a JavaScript confirmation dialog, displaying +msg+. If the user chooses 'OK', the request is launched, otherwise canceled.
|
102
102
|
*** +:condition+ => +code+ Evaluates +code+ (which should evaluate to a boolean) and proceeds if it's true, cancels the request otherwise.
|
103
103
|
*** +:before+ => +code+ Evaluates the +code+ just before launching the request. The output of the code has no influence on the execution. Typically used show a progress indicator (see this in action in the next example).
|
104
104
|
*** +:after+ => +code+ Evaluates the +code+ after launching the request. Note that this is different from the +:success+ or +:complete+ callback (covered in the next section) since those are triggered after the request is completed, while the code snippet passed to +:after+ is evaluated after the remote call is made. A common example is to disable elements on the page or otherwise prevent further action while the request is completed.
|
@@ -115,8 +115,8 @@ link_to_remote "Update record",
|
|
115
115
|
This generates a remote link which adds 2 parameters to the standard URL generated by Rails, taken from the page (contained in the elements matched by the 'status' and 'completed' DOM id).
|
116
116
|
|
117
117
|
** *Callbacks* Since an AJAX call is typically asynchronous, as it's name suggests (this is not a rule, and you can fire a synchronous request - see the last option, +:type+) your only way of communicating with a request once it is fired is via specifying callbacks. There are six options at your disposal (in fact 508, counting all possible response types, but these six are the most frequent and therefore specified by a constant):
|
118
|
-
*** +:loading:+ => +code+ The request is in the process of receiving the data, but the transfer is not completed yet.
|
119
|
-
*** +:loaded:+ => +code+ The transfer is completed, but the data is not processed and returned yet
|
118
|
+
*** +:loading:+ => +code+ The request is in the process of receiving the data, but the transfer is not completed yet.
|
119
|
+
*** +:loaded:+ => +code+ The transfer is completed, but the data is not processed and returned yet
|
120
120
|
*** +:interactive:+ => +code+ One step after +:loaded+: The data is fully received and being processed
|
121
121
|
*** +:success:+ => +code+ The data is fully received, parsed and the server responded with "200 OK"
|
122
122
|
*** +:failure:+ => +code+ The data is fully received, parsed and the server responded with *anything* but "200 OK" (typically 404 or 500, but in general with any status code ranging from 100 to 509)
|
@@ -143,15 +143,15 @@ link_to_remote "Add new item",
|
|
143
143
|
** If you specify the +href+ parameter, the AJAX link will degrade gracefully, i.e. the link will point to the URL even if JavaScript is disabled in the client browser
|
144
144
|
** +link_to_remote+ gains it's AJAX behavior by specifying the remote call in the onclick handler of the link. If you supply +html_options[:onclick]+ you override the default behavior, so use this with care!
|
145
145
|
|
146
|
-
We are finished with +link_to_remote+. I know this is quite a lot to digest for one helper function, but remember, these options are common for all the rest of the Rails view helpers, so we will take a look at the differences / additional parameters in the next sections.
|
146
|
+
We are finished with +link_to_remote+. I know this is quite a lot to digest for one helper function, but remember, these options are common for all the rest of the Rails view helpers, so we will take a look at the differences / additional parameters in the next sections.
|
147
147
|
|
148
148
|
h4. AJAX Forms
|
149
149
|
|
150
150
|
There are three different ways of adding AJAX forms to your view using Rails Prototype helpers. They are slightly different, but striving for the same goal: instead of submitting the form using the standard HTTP request/response cycle, it is submitted asynchronously, thus not reloading the page. These methods are the following:
|
151
151
|
|
152
152
|
* +remote_form_for+ (and it's alias +form_remote_for+) is tied to Rails most tightly of the three since it takes a resource, model or array of resources (in case of a nested resource) as a parameter.
|
153
|
-
* +form_remote_tag+ AJAXifies the form by serializing and sending it's data in the background
|
154
|
-
* +submit_to_remote+ and +button_to_remote+ is more rarely used than the previous two. Rather than creating an AJAX form, you add a button/input
|
153
|
+
* +form_remote_tag+ AJAXifies the form by serializing and sending it's data in the background
|
154
|
+
* +submit_to_remote+ and +button_to_remote+ is more rarely used than the previous two. Rather than creating an AJAX form, you add a button/input
|
155
155
|
|
156
156
|
Let's se them in action one by one!
|
157
157
|
|
@@ -161,7 +161,7 @@ h5. +form_remote_tag+
|
|
161
161
|
|
162
162
|
h5. +submit_to_remote+
|
163
163
|
|
164
|
-
h4. Observing Elements
|
164
|
+
h4. Observing Elements
|
165
165
|
|
166
166
|
h5. +observe_field+
|
167
167
|
|
@@ -186,10 +186,10 @@ In the last section we sent some AJAX requests to the server, and inserted the H
|
|
186
186
|
h4. Javascript without RJS
|
187
187
|
|
188
188
|
First we'll check out how to send JavaScript to the server manually. You are practically never going to need this, but it's interesting to understand what's going on under the hood.
|
189
|
-
|
189
|
+
|
190
190
|
<ruby>
|
191
191
|
def javascript_test
|
192
|
-
render :text => "alert('Hello, world!')",
|
192
|
+
render :text => "alert('Hello, world!')",
|
193
193
|
:content_type => "text/javascript"
|
194
194
|
end
|
195
195
|
</ruby>
|
@@ -207,14 +207,14 @@ def javascript_test
|
|
207
207
|
render :update do |page|
|
208
208
|
page.alert "Hello from inline RJS"
|
209
209
|
end
|
210
|
-
end
|
210
|
+
end
|
211
211
|
</ruby>
|
212
212
|
|
213
|
-
The above code snippet does exactly the same as the one in the previous section - going about it much more elegantly though. You don't need to worry about headers,write ugly JavaScript code into a string etc. When the first parameter to +render+ is +:update+, Rails expects a block with a single parameter (+page+ in our case, which is the traditional naming convention) which is an instance of the JavaScriptGenerator:"http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html" object. As it's name suggests, JavaScriptGenerator is responsible for generating JavaScript from your Ruby code. You can execute multiple method calls on the +page+ instance - it's all turned into JavaScript code and sent to the server with the appropriate Content Type, "text/javascript".
|
213
|
+
The above code snippet does exactly the same as the one in the previous section - going about it much more elegantly though. You don't need to worry about headers,write ugly JavaScript code into a string etc. When the first parameter to +render+ is +:update+, Rails expects a block with a single parameter (+page+ in our case, which is the traditional naming convention) which is an instance of the JavaScriptGenerator:"http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html" object. As it's name suggests, JavaScriptGenerator is responsible for generating JavaScript from your Ruby code. You can execute multiple method calls on the +page+ instance - it's all turned into JavaScript code and sent to the server with the appropriate Content Type, "text/javascript".
|
214
214
|
|
215
215
|
h4. RJS Templates
|
216
216
|
|
217
|
-
If you don't want to clutter your controllers with view code (especially when your inline RJS is more than a few lines), you can move your RJS code to a template file. RJS templates should go to the +/app/views/+ directory, just as +.html.erb+ or any other view files of the appropriate controller, conventionally named +js.rjs+.
|
217
|
+
If you don't want to clutter your controllers with view code (especially when your inline RJS is more than a few lines), you can move your RJS code to a template file. RJS templates should go to the +/app/views/+ directory, just as +.html.erb+ or any other view files of the appropriate controller, conventionally named +js.rjs+.
|
218
218
|
|
219
219
|
To rewrite the above example, you can leave the body of the action empty, and create a RJS template named +javascript_test.js.rjs+, containing the following line:
|
220
220
|
|
@@ -265,7 +265,7 @@ The third parameter can either be a string, or a hash of options to be passed to
|
|
265
265
|
page.insert_html :top, :result, :partial => "the_answer"
|
266
266
|
</ruby>
|
267
267
|
|
268
|
-
You can replace the contents (innerHTML) of an element with the +replace_html+ method. The only difference is that since it's clear where should the new content go, there is no need for a position parameter - so +replace_html+ takes only two arguments,
|
268
|
+
You can replace the contents (innerHTML) of an element with the +replace_html+ method. The only difference is that since it's clear where should the new content go, there is no need for a position parameter - so +replace_html+ takes only two arguments,
|
269
269
|
the DOM id of the element you wish to modify and a string or a hash of options to be passed to ActionView::Base#render.
|
270
270
|
|
271
271
|
h6. Delay
|
@@ -273,7 +273,7 @@ h6. Delay
|
|
273
273
|
You can delay the execution of a block of code with +delay+:
|
274
274
|
|
275
275
|
<ruby>
|
276
|
-
page.delay(10) { page.alert('Hey! Just waited 10 seconds') }
|
276
|
+
page.delay(10) { page.alert('Hey! Just waited 10 seconds') }
|
277
277
|
</ruby>
|
278
278
|
|
279
279
|
+delay+ takes one parameter (time to wait in seconds) and a block which will be executed after the specified time has passed - whatever else follows a +page.delay+ line is executed immediately, the delay affects only the code in the block.
|
@@ -283,7 +283,7 @@ h6. Reloading and Redirecting
|
|
283
283
|
You can reload the page with the +reload+ method:
|
284
284
|
|
285
285
|
<ruby>
|
286
|
-
page.reload
|
286
|
+
page.reload
|
287
287
|
</ruby>
|
288
288
|
|
289
289
|
When using AJAX, you can't rely on the standard +redirect_to+ controller method - you have to use the +page+'s instance method, also called +redirect_to+:
|
@@ -292,7 +292,7 @@ When using AJAX, you can't rely on the standard +redirect_to+ controller method
|
|
292
292
|
page.redirect_to some_url
|
293
293
|
</ruby>
|
294
294
|
|
295
|
-
h6. Generating Arbitrary JavaScript
|
295
|
+
h6. Generating Arbitrary JavaScript
|
296
296
|
|
297
297
|
Sometimes even the full power of RJS is not enough to accomplish everything, but you still don't want to drop to pure JavaScript. A nice golden mean is offered by the combination of +<<+, +assign+ and +call+ methods:
|
298
298
|
|
@@ -25,11 +25,11 @@ end
|
|
25
25
|
|
26
26
|
Communicate to the reader the current way of doing things, both explicitly and implicitly. Use the recommended idioms in edge, reorder sections to emphasize favored approaches if needed, etc. The documentation should be a model for best practices and canonical, modern Rails usage.
|
27
27
|
|
28
|
-
Documentation has to be concise but comprehensive. Explore and document edge cases. What happens if a module is anonymous? What if a collection is empty? What if an argument is nil?
|
28
|
+
Documentation has to be concise but comprehensive. Explore and document edge cases. What happens if a module is anonymous? What if a collection is empty? What if an argument is nil?
|
29
29
|
|
30
30
|
The proper names of Rails components have a space in between the words, like "Active Support". +ActiveRecord+ is a Ruby module, whereas Active Record is an ORM. Historically there has been lack of consistency regarding this, but we checked with David when docrails started. All Rails documentation consistently refer to Rails components by their proper name, and if in your next blog post or presentation you remember this tidbit and take it into account that'd be fenomenal :).
|
31
31
|
|
32
|
-
Spell names correctly: HTML, MySQL, JavaScript, ERb.
|
32
|
+
Spell names correctly: HTML, MySQL, JavaScript, ERb. Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite database".
|
33
33
|
|
34
34
|
h3. Example Code
|
35
35
|
|
@@ -125,7 +125,7 @@ def copy_instance_variables_from(object, exclude = [])
|
|
125
125
|
end
|
126
126
|
</ruby>
|
127
127
|
|
128
|
-
WARNING: Using a pair of ++...++ for fixed-width font only works with *words*; that is: anything matching <tt>\A\w+\z</tt>. For anything else use +<tt>...</tt>+, notably symbols, setters, inline snippets, etc:
|
128
|
+
WARNING: Using a pair of ++...++ for fixed-width font only works with *words*; that is: anything matching <tt>\A\w+\z</tt>. For anything else use +<tt>...</tt>+, notably symbols, setters, inline snippets, etc:
|
129
129
|
|
130
130
|
h4. Regular Font
|
131
131
|
|
@@ -1401,8 +1401,8 @@ person = Person.create(:name => 'honda')
|
|
1401
1401
|
post = Post.create(:name => 'a1')
|
1402
1402
|
person.posts << post
|
1403
1403
|
person.posts << post
|
1404
|
-
person.posts.inspect # => [#<Post id: 7, name: "a1">]
|
1405
|
-
Reading.all.inspect # => [#<Reading id: 16, person_id: 7, post_id: 7>, #<Reading id: 17, person_id: 7, post_id: 7>]
|
1404
|
+
person.posts.inspect # => [#<Post id: 7, name: "a1">]
|
1405
|
+
Reading.all.inspect # => [#<Reading id: 16, person_id: 7, post_id: 7>, #<Reading id: 17, person_id: 7, post_id: 7>]
|
1406
1406
|
</ruby>
|
1407
1407
|
|
1408
1408
|
In the above case there are still two readings. However +person.posts+ shows only one post because the collection loads only unique records.
|
@@ -98,7 +98,7 @@ You can also use +:if+ (or +:unless+) to pass a Proc that specifies when the act
|
|
98
98
|
|
99
99
|
You can modify the default action cache path by passing a +:cache_path+ option. This will be passed directly to +ActionCachePath.path_for+. This is handy for actions with multiple possible routes that should be cached differently. If a block is given, it is called with the current controller instance.
|
100
100
|
|
101
|
-
Finally, if you are using memcached, you can also pass +:expires_in+. In fact, all parameters not used by +caches_action+ are sent to the underlying cache store.
|
101
|
+
Finally, if you are using memcached, you can also pass +:expires_in+. In fact, all parameters not used by +caches_action+ are sent to the underlying cache store.
|
102
102
|
|
103
103
|
INFO: Action caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Typically, a redirection in some before filter that checks request preconditions does the job.
|
104
104
|
|
@@ -242,12 +242,12 @@ Rails 2.1 and above provide +ActiveSupport::Cache::Store+ which can be used to c
|
|
242
242
|
|
243
243
|
The default cache stores provided with Rails include:
|
244
244
|
|
245
|
-
1) +ActiveSupport::Cache::MemoryStore+: A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances won't be able to share cache data with each other. If your application never performs manual cache item expiry (e.g. when you‘re using generational cache keys), then using +MemoryStore+ is ok. Otherwise, consider carefully whether you should be using this cache store.
|
245
|
+
1) +ActiveSupport::Cache::MemoryStore+: A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances won't be able to share cache data with each other. If your application never performs manual cache item expiry (e.g. when you‘re using generational cache keys), then using +MemoryStore+ is ok. Otherwise, consider carefully whether you should be using this cache store.
|
246
246
|
|
247
247
|
+MemoryStore+ is not only able to store strings, but also arbitrary Ruby objects.
|
248
248
|
|
249
249
|
+MemoryStore+ is not thread-safe. Use +SynchronizedMemoryStore+ instead if you need thread-safety.
|
250
|
-
|
250
|
+
|
251
251
|
<ruby>
|
252
252
|
ActionController::Base.cache_store = :memory_store
|
253
253
|
</ruby>
|
@@ -280,7 +280,7 @@ It also accepts a hash of additional options:
|
|
280
280
|
|
281
281
|
The read and write methods of the +MemCacheStore+ accept an options hash too. When reading you can specify +:raw => true+ to prevent the object being marshaled (by default this is false which means the raw value in the cache is passed to +Marshal.load+ before being returned to you.)
|
282
282
|
|
283
|
-
When writing to the cache it is also possible to specify +:raw => true+ means the value is not passed to +Marshal.dump+ before being stored in the cache (by default this is false).
|
283
|
+
When writing to the cache it is also possible to specify +:raw => true+ means the value is not passed to +Marshal.dump+ before being stored in the cache (by default this is false).
|
284
284
|
|
285
285
|
The write method also accepts an +:unless_exist+ flag which determines whether the memcached add (when true) or set (when false) method is used to store the item in the cache and an +:expires_in+ option that specifies the time-to-live for the cached item in seconds.
|
286
286
|
|
@@ -367,7 +367,7 @@ h3. Advanced Caching
|
|
367
367
|
Along with the built-in mechanisms outlined above, a number of excellent plugins exist to help with finer grained control over caching. These include Chris Wanstrath's excellent cache_fu plugin (more info "here": http://errtheblog.com/posts/57-kickin-ass-w-cachefu) and Evan Weaver's interlock plugin (more info "here": http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/). Both of these plugins play nice with memcached and are a must-see for anyone
|
368
368
|
seriously considering optimizing their caching needs.
|
369
369
|
|
370
|
-
Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plugin is supposed to be mad cool.
|
370
|
+
Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plugin is supposed to be mad cool.
|
371
371
|
|
372
372
|
h3. References
|
373
373
|
|
@@ -23,19 +23,19 @@ There are a few commands that are absolutely critical to your everyday usage of
|
|
23
23
|
* <tt>rake</tt>
|
24
24
|
* <tt>rails generate</tt>
|
25
25
|
* <tt>rails dbconsole</tt>
|
26
|
-
* <tt>rails app_name</tt>
|
26
|
+
* <tt>rails new app_name</tt>
|
27
27
|
|
28
28
|
Let's create a simple Rails application to step through each of these commands in context.
|
29
29
|
|
30
|
-
h4. +rails+
|
30
|
+
h4. +rails new+
|
31
31
|
|
32
|
-
The first thing we'll want to do is create a new Rails application by running the +rails+ command after installing Rails.
|
32
|
+
The first thing we'll want to do is create a new Rails application by running the +rails new+ command after installing Rails.
|
33
33
|
|
34
34
|
WARNING: You know you need the rails gem installed by typing +gem install rails+ first, if you don't have this installed, follow the instructions in the "Rails 3 Release Notes":/3_0_release_notes.html
|
35
35
|
|
36
36
|
<shell>
|
37
|
-
$ rails commandsapp
|
38
|
-
create
|
37
|
+
$ rails new commandsapp
|
38
|
+
create
|
39
39
|
create README
|
40
40
|
create .gitignore
|
41
41
|
create Rakefile
|
@@ -352,7 +352,7 @@ $ mkdir gitapp
|
|
352
352
|
$ cd gitapp
|
353
353
|
$ git init
|
354
354
|
Initialized empty Git repository in .git/
|
355
|
-
$ rails . --git --database=postgresql
|
355
|
+
$ rails new . --git --database=postgresql
|
356
356
|
exists
|
357
357
|
create app/controllers
|
358
358
|
create app/helpers
|
@@ -397,7 +397,7 @@ development:
|
|
397
397
|
...
|
398
398
|
</shell>
|
399
399
|
|
400
|
-
It also generated some lines in our database.yml configuration corresponding to our choice of PostgreSQL for database. The only catch with using the SCM options is that you have to make your application's directory first, then initialize your SCM, then you can run the +rails+ command to generate the basis of your app.
|
400
|
+
It also generated some lines in our database.yml configuration corresponding to our choice of PostgreSQL for database. The only catch with using the SCM options is that you have to make your application's directory first, then initialize your SCM, then you can run the +rails new+ command to generate the basis of your app.
|
401
401
|
|
402
402
|
h4. +server+ with Different Backends
|
403
403
|
|
@@ -570,7 +570,7 @@ h5. +test:+ Rails tests
|
|
570
570
|
|
571
571
|
INFO: A good description of unit testing in Rails is given in "A Guide to Testing Rails Applications":testing.html
|
572
572
|
|
573
|
-
Rails comes with a test suite called Test::Unit. It is through the use of tests that Rails itself is so stable, and the slew of people working on Rails can prove that everything works as it should.
|
573
|
+
Rails comes with a test suite called Test::Unit. It is through the use of tests that Rails itself is so stable, and the slew of people working on Rails can prove that everything works as it should.
|
574
574
|
|
575
575
|
The +test:+ namespace helps in running the different tests you will (hopefully!) write.
|
576
576
|
|
@@ -51,15 +51,15 @@ h4. Rails General Configuration
|
|
51
51
|
|
52
52
|
* +config.dependency_loading+ enables or disables dependency loading during the request cycle. Setting dependency_loading to _true_ will allow new classes to be loaded during a request and setting it to _false_ will disable this behavior.
|
53
53
|
|
54
|
-
* +config.eager_load_paths+ accepts an array of paths from which Rails will eager load on boot if cache classes is enabled. All elements of this array must also be in +load_paths+.
|
54
|
+
* +config.eager_load_paths+ accepts an array of paths from which Rails will eager load on boot if cache classes is enabled. All elements of this array must also be in +load_paths+.
|
55
55
|
|
56
56
|
* +config.load_once_paths+ accepts an array of paths from which Rails will automatically load from only once. All elements of this array must also be in +load_paths+.
|
57
57
|
|
58
|
-
* +config.load_paths+ accepts an array of additional paths to prepend to the load path. By default, all app, lib, vendor and mock paths are included in this list.
|
58
|
+
* +config.load_paths+ accepts an array of additional paths to prepend to the load path. By default, all app, lib, vendor and mock paths are included in this list.
|
59
59
|
|
60
|
-
* +config.log_level+ defines the verbosity of the Rails logger. In production mode, this defaults to +:info+. In development mode, it defaults to +:debug+.
|
60
|
+
* +config.log_level+ defines the verbosity of the Rails logger. In production mode, this defaults to +:info+. In development mode, it defaults to +:debug+.
|
61
61
|
|
62
|
-
* +config.log_path+ overrides the path to the log file to use. Defaults to +log/#{environment}.log+ (e.g. log/development.log or log/production.log).
|
62
|
+
* +config.log_path+ overrides the path to the log file to use. Defaults to +log/#{environment}.log+ (e.g. log/development.log or log/production.log).
|
63
63
|
|
64
64
|
* +config.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Controller. Set to nil to disable logging.
|
65
65
|
|
@@ -73,7 +73,7 @@ h4. Rails General Configuration
|
|
73
73
|
|
74
74
|
* +config.preload_frameworks+ enables or disables preloading all frameworks at startup.
|
75
75
|
|
76
|
-
* +config.reload_plugins+ enables or disables plugin reloading.
|
76
|
+
* +config.reload_plugins+ enables or disables plugin reloading.
|
77
77
|
|
78
78
|
* +config.root_path+ configures the root path of the application.
|
79
79
|
|
@@ -181,7 +181,7 @@ There are only a few configuration options for Action View, starting with four o
|
|
181
181
|
|
182
182
|
* +config.action_view.warn_cache_misses+ tells Rails to display a warning whenever an action results in a cache miss on your view paths. The default is +false+.
|
183
183
|
|
184
|
-
* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance|
|
184
|
+
* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| %Q(%<div class="field_with_errors">#{html_tag}</div>).html_safe }</tt>
|
185
185
|
|
186
186
|
* +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+.
|
187
187
|
|
@@ -48,7 +48,7 @@ h4. Install git
|
|
48
48
|
|
49
49
|
Rails uses git for source code control. You won’t be able to do anything without the Rails source code, and this is a prerequisite. The "git homepage":http://git-scm.com/ has installation instructions. If you’re on OS X, use the "Git for OS X":http://code.google.com/p/git-osx-installer/ installer. If you're unfamiliar with git, there are a variety of resources on the net that will help you learn more:
|
50
50
|
|
51
|
-
* "Everyday Git":http://www.kernel.org/pub/software/scm/git/docs/everyday.html will teach you just enough about git to get by.
|
51
|
+
* "Everyday Git":http://www.kernel.org/pub/software/scm/git/docs/everyday.html will teach you just enough about git to get by.
|
52
52
|
* The "PeepCode screencast":https://peepcode.com/products/git on git ($9) is easier to follow.
|
53
53
|
* "GitHub":http://github.com/guides/home offers links to a variety of git resources.
|
54
54
|
* "Pro Git":http://progit.org/book/ is an entire book about git with a Creative Commons license.
|
@@ -58,7 +58,7 @@ h4. Get the Rails Source Code
|
|
58
58
|
Don’t fork the main Rails repository. Instead, you want to clone it to your own computer. Navigate to the folder where you want the source code (it will create its own /rails subdirectory) and run:
|
59
59
|
|
60
60
|
<shell>
|
61
|
-
git clone git://github.com/rails/rails.git
|
61
|
+
git clone git://github.com/rails/rails.git
|
62
62
|
cd rails
|
63
63
|
</shell>
|
64
64
|
|
@@ -66,8 +66,10 @@ h4. Set up and Run the Tests
|
|
66
66
|
|
67
67
|
All of the Rails tests must pass with any code you submit, otherwise you have no chance of getting code accepted. This means you need to be able to run the tests. First, you need to install all Rails dependencies with bundler:
|
68
68
|
|
69
|
+
NOTE: Ensure you install bundler v1.0
|
70
|
+
|
69
71
|
<shell>
|
70
|
-
gem install bundler
|
72
|
+
gem install -v=1.0.0.rc.6 bundler
|
71
73
|
bundle install --without db
|
72
74
|
</shell>
|
73
75
|
|
@@ -90,7 +92,7 @@ By default, when you run Active Record tests, it will execute the test suite thr
|
|
90
92
|
|
91
93
|
<shell>
|
92
94
|
cd activerecord
|
93
|
-
rake test_sqlite3
|
95
|
+
rake test_sqlite3
|
94
96
|
rake test_sqlite3 TEST=test/cases/validations_test.rb
|
95
97
|
</shell>
|
96
98
|
|
@@ -258,15 +260,15 @@ h4. Update Rails
|
|
258
260
|
Update your copy of Rails. It’s pretty likely that other changes to core Rails have happened while you were working. Go get them:
|
259
261
|
|
260
262
|
<shell>
|
261
|
-
git checkout master
|
262
|
-
git pull
|
263
|
+
git checkout master
|
264
|
+
git pull
|
263
265
|
</shell>
|
264
266
|
|
265
267
|
Now reapply your patch on top of the latest changes:
|
266
268
|
|
267
269
|
<shell>
|
268
|
-
git checkout my_new_branch
|
269
|
-
git rebase master
|
270
|
+
git checkout my_new_branch
|
271
|
+
git rebase master
|
270
272
|
</shell>
|
271
273
|
|
272
274
|
No conflicts? Tests still pass? Change still seems reasonable to you? Then move on.
|
@@ -276,8 +278,8 @@ h4. Create a Patch
|
|
276
278
|
Now you can create a patch file to share with other developers (and with the Rails core team). Still in your branch, run
|
277
279
|
|
278
280
|
<shell>
|
279
|
-
git commit -a
|
280
|
-
git format-patch master --stdout > my_new_patch.diff
|
281
|
+
git commit -a
|
282
|
+
git format-patch master --stdout > my_new_patch.diff
|
281
283
|
</shell>
|
282
284
|
|
283
285
|
Sanity check the results of this operation: open the diff file in your text editor of choice and make sure that no unintended changes crept in.
|
@@ -302,4 +304,5 @@ h3. Changelog
|
|
302
304
|
|
303
305
|
* April 6, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
|
304
306
|
* August 1, 2009: Updates/amplifications by "Mike Gunderloy":credits.html#mgunderloy
|
305
|
-
* March 2, 2009: Initial draft by "Mike Gunderloy":credits.html#mgunderloy
|
307
|
+
* March 2, 2009: Initial draft by "Mike Gunderloy":credits.html#mgunderloy
|
308
|
+
|
@@ -96,23 +96,25 @@ Will be rendered as follows:
|
|
96
96
|
Title: Rails debugging guide
|
97
97
|
</pre>
|
98
98
|
|
99
|
-
h4. Debugging
|
99
|
+
h4. Debugging RJS
|
100
100
|
|
101
|
-
Rails has built-in support to debug RJS
|
101
|
+
Rails has optional built-in support to debug RJS. When enabled, responses are wrapped in a try/catch block that displays the caught exception using +alert()+, and then re-raises it.
|
102
102
|
|
103
|
-
|
103
|
+
The flag to enable RJS debugging in your configuration files is +config.action_view.debug_rjs+:
|
104
104
|
|
105
105
|
<ruby>
|
106
|
-
config.action_view
|
106
|
+
config.action_view.debug_rjs = true
|
107
107
|
</ruby>
|
108
108
|
|
109
|
-
|
109
|
+
or at any time setting +ActionView::Base.debug_rjs+:
|
110
110
|
|
111
111
|
<ruby>
|
112
112
|
ActionView::Base.debug_rjs = true
|
113
113
|
</ruby>
|
114
114
|
|
115
|
-
|
115
|
+
It is enabled by default in development mode, and disabled in the rest.
|
116
|
+
|
117
|
+
TIP: For more information on debugging JavaScript, refer to "Firebug":http://getfirebug.com/, the popular debugger for Firefox.
|
116
118
|
|
117
119
|
h3. The Logger
|
118
120
|
|
@@ -647,7 +647,7 @@ the +params+ hash will contain
|
|
647
647
|
{'person' => {'name' => 'Henry'}}
|
648
648
|
</erb>
|
649
649
|
|
650
|
-
and +params[
|
650
|
+
and +params[:person][:name]+ will retrieve the submitted value in the controller.
|
651
651
|
|
652
652
|
Hashes can be nested as many levels as required, for example
|
653
653
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
h2. Creating and Customizing Rails Generators
|
2
2
|
|
3
|
-
Rails generators are an essential tool if you plan to improve your workflow
|
3
|
+
Rails generators are an essential tool if you plan to improve your workflow. With this guide you will learn how to create generators and customize existing ones.
|
4
4
|
|
5
5
|
In this guide you will:
|
6
6
|
|
@@ -13,7 +13,7 @@ In this guide you will:
|
|
13
13
|
|
14
14
|
endprologue.
|
15
15
|
|
16
|
-
NOTE: This guide is about
|
16
|
+
NOTE: This guide is about generators in Rails 3, previous versions are not covered.
|
17
17
|
|
18
18
|
h3. First Contact
|
19
19
|
|
@@ -35,7 +35,7 @@ h3. Creating Your First Generator
|
|
35
35
|
|
36
36
|
Since Rails 3.0, generators are built on top of "Thor":http://github.com/wycats/thor. Thor provides powerful options parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named +initializer.rb+ inside +config/initializers+.
|
37
37
|
|
38
|
-
The first step is to create a file at +
|
38
|
+
The first step is to create a file at +lib/generators/initializer_generator.rb+ with the following content:
|
39
39
|
|
40
40
|
<ruby>
|
41
41
|
class InitializerGenerator < Rails::Generators::Base
|
@@ -74,7 +74,7 @@ Now we can see the new description by invoking +--help+ on the new generator. Th
|
|
74
74
|
|
75
75
|
h3. Creating Generators with Generators
|
76
76
|
|
77
|
-
|
77
|
+
Generators themselves have a generator:
|
78
78
|
|
79
79
|
<shell>
|
80
80
|
$ rails generate generator initializer
|
@@ -84,7 +84,7 @@ $ rails generate generator initializer
|
|
84
84
|
create lib/generators/initializer/templates
|
85
85
|
</shell>
|
86
86
|
|
87
|
-
|
87
|
+
This is the generator just created:
|
88
88
|
|
89
89
|
<ruby>
|
90
90
|
class InitializerGenerator < Rails::Generators::NamedBase
|
@@ -92,7 +92,7 @@ class InitializerGenerator < Rails::Generators::NamedBase
|
|
92
92
|
end
|
93
93
|
</ruby>
|
94
94
|
|
95
|
-
First, notice that we are inheriting from +Rails::Generators::NamedBase+ instead of +Rails::Generators::Base+. This means that our generator expects
|
95
|
+
First, notice that we are inheriting from +Rails::Generators::NamedBase+ instead of +Rails::Generators::Base+. This means that our generator expects at least one argument, which will be the name of the initializer.
|
96
96
|
|
97
97
|
We can see that by invoking the description of this new generator (don't forget to delete the old generator file):
|
98
98
|
|
@@ -102,7 +102,9 @@ Usage:
|
|
102
102
|
rails generate initializer NAME [options]
|
103
103
|
</shell>
|
104
104
|
|
105
|
-
We can also see
|
105
|
+
We can also see that our new generator has a class method called +source_root+. This method points to where our generator templates will be placed, if any, and by default it points to the created directory +lib/generators/initializer/templates+.
|
106
|
+
|
107
|
+
In order to understand what a generator template means, let's create the file +lib/generators/initializer/templates/initializer.rb+ with the following content:
|
106
108
|
|
107
109
|
<ruby>
|
108
110
|
# Add initialization content here
|
@@ -124,16 +126,14 @@ end
|
|
124
126
|
And let's execute our generator:
|
125
127
|
|
126
128
|
<shell>
|
127
|
-
$ rails generate initializer
|
129
|
+
$ rails generate initializer core_extensions
|
128
130
|
</shell>
|
129
131
|
|
130
|
-
We can see that now a initializer named
|
132
|
+
We can see that now a initializer named core_extensions was created at +config/initializers/core_extensions.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
|
131
133
|
|
132
134
|
h3. Generators Lookup
|
133
135
|
|
134
|
-
|
135
|
-
|
136
|
-
For instance, when you say +rails generate initializer foo+, Rails knows you want to invoke the initializer generator and then search for the following generators in the $LOAD_PATHS:
|
136
|
+
When you run +rails generate initializer core_extensions+ Rails requires these files in turn until one is found:
|
137
137
|
|
138
138
|
<shell>
|
139
139
|
rails/generators/initializer/initializer_generator.rb
|
@@ -142,11 +142,13 @@ rails/generators/initializer_generator.rb
|
|
142
142
|
generators/initializer_generator.rb
|
143
143
|
</shell>
|
144
144
|
|
145
|
-
If none
|
145
|
+
If none is found you get an error message.
|
146
|
+
|
147
|
+
INFO: The examples above put files under the application's +lib+ because said directoty belongs to +$LOAD_PATH+.
|
146
148
|
|
147
149
|
h3. Customizing Your Workflow
|
148
150
|
|
149
|
-
Rails generators are flexible enough to let you customize
|
151
|
+
Rails own generators are flexible enough to let you customize scaffolding. They can be configured in +config/application.rb+, these are some defaults:
|
150
152
|
|
151
153
|
<ruby>
|
152
154
|
config.generators do |g|
|
@@ -166,7 +168,7 @@ $ rails generate scaffold User name:string
|
|
166
168
|
invoke test_unit
|
167
169
|
create test/unit/user_test.rb
|
168
170
|
create test/fixtures/users.yml
|
169
|
-
route
|
171
|
+
route resources :users
|
170
172
|
invoke scaffold_controller
|
171
173
|
create app/controllers/users_controller.rb
|
172
174
|
invoke erb
|
@@ -186,9 +188,9 @@ $ rails generate scaffold User name:string
|
|
186
188
|
create public/stylesheets/scaffold.css
|
187
189
|
</shell>
|
188
190
|
|
189
|
-
Looking at this output, it's easy to understand how generators work
|
191
|
+
Looking at this output, it's easy to understand how generators work in Rails 3.0 and above. The scaffold generator doesn't actually generate anything, it just invokes others to do the work. This allows us to add/replace/remove any of those invocations. For instance, the scaffold generator invokes the scaffold_controller generator, which invokes erb, test_unit and helper generators. Since each generator has a single responsibility, they are easy to reuse, avoiding code duplication.
|
190
192
|
|
191
|
-
Our first customization on the workflow will be to stop generating stylesheets and test fixtures
|
193
|
+
Our first customization on the workflow will be to stop generating stylesheets and test fixtures for scaffolds. We can achieve that by changing our configuration to the following:
|
192
194
|
|
193
195
|
<ruby>
|
194
196
|
config.generators do |g|
|
@@ -199,7 +201,7 @@ config.generators do |g|
|
|
199
201
|
end
|
200
202
|
</ruby>
|
201
203
|
|
202
|
-
If we generate another resource
|
204
|
+
If we generate another resource with the scaffold generator, we can notice that neither stylesheets nor fixtures are created anymore. If you want to customize it further, for example to use DataMapper and RSpec instead of Active Record and TestUnit, it's just a matter of adding their gems to your application and configuring your generators.
|
203
205
|
|
204
206
|
To demonstrate this, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator:
|
205
207
|
|
@@ -224,18 +226,18 @@ end
|
|
224
226
|
We can try out our new generator by creating a helper for users:
|
225
227
|
|
226
228
|
<shell>
|
227
|
-
$ rails generate my_helper
|
229
|
+
$ rails generate my_helper products
|
228
230
|
</shell>
|
229
231
|
|
230
232
|
And it will generate the following helper file in +app/helpers+:
|
231
233
|
|
232
234
|
<ruby>
|
233
|
-
module
|
234
|
-
attr_reader :
|
235
|
+
module ProductsHelper
|
236
|
+
attr_reader :products, :product
|
235
237
|
end
|
236
238
|
</ruby>
|
237
239
|
|
238
|
-
Which is what we expected. We can now tell scaffold to use our new helper generator by
|
240
|
+
Which is what we expected. We can now tell scaffold to use our new helper generator by editing +config/application.rb+ once again:
|
239
241
|
|
240
242
|
<ruby>
|
241
243
|
config.generators do |g|
|
@@ -247,7 +249,7 @@ config.generators do |g|
|
|
247
249
|
end
|
248
250
|
</ruby>
|
249
251
|
|
250
|
-
|
252
|
+
and see it in action when invoking the generator:
|
251
253
|
|
252
254
|
<shell>
|
253
255
|
$ rails generate scaffold Post body:text
|
@@ -260,7 +262,7 @@ We can notice on the output that our new helper was invoked instead of the Rails
|
|
260
262
|
|
261
263
|
Since Rails 3.0, this is easy to do due to the hooks concept. Our new helper does not need to be focused in one specific test framework, it can simply provide a hook and a test framework just needs to implement this hook in order to be compatible.
|
262
264
|
|
263
|
-
To do that, we can change
|
265
|
+
To do that, we can change the generator this way:
|
264
266
|
|
265
267
|
<ruby>
|
266
268
|
class MyHelperGenerator < Rails::Generators::NamedBase
|
@@ -287,9 +289,9 @@ And now you can re-run scaffold for another resource and see it generating tests
|
|
287
289
|
|
288
290
|
h3. Customizing Your Workflow by Changing Generators Templates
|
289
291
|
|
290
|
-
In the step above
|
292
|
+
In the step above we simply wanted to add a line to the generated helper, without adding any extra functionality. There is a simpler way to do that, and it's by replacing the templates of already existing generators, in that case +Rails::Generators::HelperGenerator+.
|
291
293
|
|
292
|
-
In Rails 3.0 and above, generators don't just look in the source root for templates, they also search for templates in other paths. And one of them is
|
294
|
+
In Rails 3.0 and above, generators don't just look in the source root for templates, they also search for templates in other paths. And one of them is +lib/templates+. Since we want to customize +Rails::Generators::HelperGenerator+, we can do that by simply making a template copy inside +lib/templates/rails/helper+ with the name +helper.rb+. So let's create that file with the following content:
|
293
295
|
|
294
296
|
<erb>
|
295
297
|
module <%= class_name %>Helper
|
@@ -297,7 +299,7 @@ module <%= class_name %>Helper
|
|
297
299
|
end
|
298
300
|
</erb>
|
299
301
|
|
300
|
-
|
302
|
+
and revert the last change in +config/application.rb+:
|
301
303
|
|
302
304
|
<ruby>
|
303
305
|
config.generators do |g|
|
@@ -308,11 +310,11 @@ config.generators do |g|
|
|
308
310
|
end
|
309
311
|
</ruby>
|
310
312
|
|
311
|
-
If you generate another resource, you can see that we
|
313
|
+
If you generate another resource, you can see that we get exactly the same result! This is useful if you want to customize your scaffold templates and/or layout by just creating +edit.html.erb+, +index.html.erb+ and so on inside +lib/templates/erb/scaffold+.
|
312
314
|
|
313
315
|
h3. Adding Generators Fallbacks
|
314
316
|
|
315
|
-
One last feature about generators which is quite useful for plugin generators is fallbacks. For example, imagine that you want to add a feature on top of TestUnit
|
317
|
+
One last feature about generators which is quite useful for plugin generators is fallbacks. For example, imagine that you want to add a feature on top of TestUnit like "shoulda":http://github.com/thoughtbot/shoulda does. Since TestUnit already implements all generators required by Rails and shoulda just wants to overwrite part of it, there is no need for shoulda to reimplement some generators again, it can simply tell Rails to use a +TestUnit+ generator if none was found under the +Shoulda+ namespace.
|
316
318
|
|
317
319
|
We can easily simulate this behavior by changing our +config/application.rb+ once again:
|
318
320
|
|
@@ -328,7 +330,7 @@ config.generators do |g|
|
|
328
330
|
end
|
329
331
|
</ruby>
|
330
332
|
|
331
|
-
Now, if you create a Comment scaffold, you will see that the shoulda generators are being invoked, and at the end, they are just falling back to
|
333
|
+
Now, if you create a Comment scaffold, you will see that the shoulda generators are being invoked, and at the end, they are just falling back to TestUnit generators:
|
332
334
|
|
333
335
|
<shell>
|
334
336
|
$ rails generate scaffold Comment body:text
|
@@ -363,6 +365,8 @@ h3. Changelog
|
|
363
365
|
|
364
366
|
"Lighthouse Ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/102
|
365
367
|
|
368
|
+
* August 23, 2010: Edit pass by "Xavier Noria":credits.html#fxn
|
369
|
+
|
366
370
|
* April 30, 2010: Reviewed by José Valim
|
367
371
|
|
368
372
|
* November 20, 2009: First version by José Valim
|