rails 4.0.13 → 4.1.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -17
- data/guides/CHANGELOG.md +68 -34
- data/guides/assets/images/edge_badge.png +0 -0
- data/guides/assets/images/feature_tile.gif +0 -0
- data/guides/assets/images/footer_tile.gif +0 -0
- data/guides/assets/images/fxn.png +0 -0
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/assets/images/getting_started/challenge.png +0 -0
- data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
- data/guides/assets/images/getting_started/form_with_errors.png +0 -0
- data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
- data/guides/assets/images/getting_started/new_article.png +0 -0
- data/guides/assets/images/getting_started/rails_welcome.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
- data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
- data/guides/assets/images/header_tile.gif +0 -0
- data/guides/assets/images/icons/README +1 -1
- data/guides/assets/images/icons/callouts/11.png +0 -0
- data/guides/assets/images/icons/callouts/12.png +0 -0
- data/guides/assets/images/icons/callouts/13.png +0 -0
- data/guides/assets/images/icons/callouts/15.png +0 -0
- data/guides/assets/images/icons/caution.png +0 -0
- data/guides/assets/images/icons/example.png +0 -0
- data/guides/assets/images/radar.png +0 -0
- data/guides/assets/images/rails4_features.png +0 -0
- data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
- data/guides/assets/images/vijaydev.jpg +0 -0
- data/guides/assets/javascripts/guides.js +30 -34
- data/guides/assets/stylesheets/main.css +2 -1
- data/guides/assets/stylesheets/print.css +1 -1
- data/guides/bug_report_templates/action_controller_gem.rb +9 -4
- data/guides/bug_report_templates/action_controller_master.rb +4 -2
- data/guides/bug_report_templates/active_record_gem.rb +5 -2
- data/guides/bug_report_templates/active_record_master.rb +2 -1
- data/guides/bug_report_templates/generic_gem.rb +15 -0
- data/guides/bug_report_templates/generic_master.rb +26 -0
- data/guides/code/getting_started/Gemfile +21 -24
- data/guides/code/getting_started/Gemfile.lock +78 -73
- data/guides/code/getting_started/Rakefile +1 -1
- data/guides/code/getting_started/app/assets/javascripts/application.js +1 -2
- data/guides/code/getting_started/app/views/layouts/application.html.erb +2 -2
- data/guides/code/getting_started/config/environment.rb +1 -1
- data/guides/code/getting_started/config/environments/development.rb +2 -2
- data/guides/code/getting_started/config/environments/production.rb +3 -3
- data/guides/code/getting_started/config/environments/test.rb +2 -2
- data/guides/code/getting_started/config/initializers/secret_token.rb +1 -1
- data/guides/code/getting_started/config/initializers/session_store.rb +1 -1
- data/guides/code/getting_started/config/routes.rb +1 -1
- data/guides/code/getting_started/config.ru +1 -1
- data/guides/code/getting_started/public/404.html +2 -0
- data/guides/code/getting_started/public/422.html +2 -0
- data/guides/code/getting_started/public/500.html +2 -0
- data/guides/code/getting_started/test/test_helper.rb +0 -3
- data/guides/rails_guides/helpers.rb +3 -1
- data/guides/source/2_2_release_notes.md +2 -2
- data/guides/source/2_3_release_notes.md +8 -8
- data/guides/source/3_0_release_notes.md +2 -3
- data/guides/source/3_1_release_notes.md +2 -2
- data/guides/source/3_2_release_notes.md +12 -12
- data/guides/source/4_0_release_notes.md +79 -46
- data/guides/source/4_1_release_notes.md +731 -0
- data/guides/source/_welcome.html.erb +5 -2
- data/guides/source/action_controller_overview.md +189 -40
- data/guides/source/action_mailer_basics.md +27 -27
- data/guides/source/action_view_overview.md +131 -20
- data/guides/source/active_model_basics.md +6 -6
- data/guides/source/active_record_basics.md +15 -15
- data/guides/source/active_record_callbacks.md +18 -16
- data/guides/source/active_record_querying.md +93 -51
- data/guides/source/active_record_validations.md +26 -24
- data/guides/source/active_support_core_extensions.md +72 -118
- data/guides/source/active_support_instrumentation.md +13 -4
- data/guides/source/api_documentation_guidelines.md +104 -6
- data/guides/source/asset_pipeline.md +573 -244
- data/guides/source/association_basics.md +94 -22
- data/guides/source/caching_with_rails.md +15 -6
- data/guides/source/command_line.md +55 -46
- data/guides/source/configuring.md +248 -52
- data/guides/source/contributing_to_ruby_on_rails.md +18 -17
- data/guides/source/credits.html.erb +2 -2
- data/guides/source/debugging_rails_applications.md +39 -8
- data/guides/source/development_dependencies_install.md +91 -8
- data/guides/source/documents.yaml +4 -0
- data/guides/source/engines.md +678 -232
- data/guides/source/form_helpers.md +53 -35
- data/guides/source/generators.md +19 -15
- data/guides/source/getting_started.md +758 -497
- data/guides/source/i18n.md +64 -28
- data/guides/source/index.html.erb +1 -1
- data/guides/source/initialization.md +155 -58
- data/guides/source/kindle/toc.html.erb +1 -1
- data/guides/source/layout.html.erb +2 -2
- data/guides/source/layouts_and_rendering.md +59 -26
- data/guides/source/maintenance_policy.md +3 -3
- data/guides/source/migrations.md +101 -62
- data/guides/source/nested_model_forms.md +3 -3
- data/guides/source/plugins.md +34 -31
- data/guides/source/rails_application_templates.md +27 -8
- data/guides/source/rails_on_rack.md +41 -58
- data/guides/source/routing.md +115 -104
- data/guides/source/ruby_on_rails_guides_guidelines.md +2 -2
- data/guides/source/security.md +81 -36
- data/guides/source/testing.md +56 -79
- data/guides/source/upgrading_ruby_on_rails.md +531 -21
- data/guides/source/working_with_javascript_in_rails.md +19 -11
- metadata +51 -23
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
- data/guides/assets/images/getting_started/new_post.png +0 -0
- data/guides/assets/images/getting_started/post_with_comments.png +0 -0
- data/guides/assets/images/getting_started/show_action_for_posts.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_posts_new.png +0 -0
- data/guides/assets/images/getting_started/undefined_method_post_path.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_posts.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_posts.png +0 -0
- data/guides/assets/images/jaimeiniesta.jpg +0 -0
- data/guides/source/kindle/KINDLE.md +0 -26
@@ -67,7 +67,7 @@ To create this form you will use `form_tag`, `label_tag`, `text_field_tag`, and
|
|
67
67
|
This will generate the following HTML:
|
68
68
|
|
69
69
|
```html
|
70
|
-
<form accept-charset="UTF-8" action="/search" method="get">
|
70
|
+
<form accept-charset="UTF-8" action="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div>
|
71
71
|
<label for="q">Search for:</label>
|
72
72
|
<input id="q" name="q" type="text" />
|
73
73
|
<input name="commit" type="submit" value="Search" />
|
@@ -154,7 +154,10 @@ make it easier for users to click the inputs.
|
|
154
154
|
|
155
155
|
### Other Helpers of Interest
|
156
156
|
|
157
|
-
Other form controls worth mentioning are textareas, password fields,
|
157
|
+
Other form controls worth mentioning are textareas, password fields,
|
158
|
+
hidden fields, search fields, telephone fields, date fields, time fields,
|
159
|
+
color fields, datetime fields, datetime-local fields, month fields, week fields,
|
160
|
+
URL fields, email fields, number fields and range fields:
|
158
161
|
|
159
162
|
```erb
|
160
163
|
<%= text_area_tag(:message, "Hi, nice site", size: "24x6") %>
|
@@ -171,6 +174,8 @@ Other form controls worth mentioning are textareas, password fields, hidden fiel
|
|
171
174
|
<%= email_field(:user, :address) %>
|
172
175
|
<%= color_field(:user, :favorite_color) %>
|
173
176
|
<%= time_field(:task, :started_at) %>
|
177
|
+
<%= number_field(:product, :price, in: 1.0..20.0, step: 0.5) %>
|
178
|
+
<%= range_field(:product, :discount, in: 1..100) %>
|
174
179
|
```
|
175
180
|
|
176
181
|
Output:
|
@@ -190,11 +195,20 @@ Output:
|
|
190
195
|
<input id="user_address" name="user[address]" type="email" />
|
191
196
|
<input id="user_favorite_color" name="user[favorite_color]" type="color" value="#000000" />
|
192
197
|
<input id="task_started_at" name="task[started_at]" type="time" />
|
198
|
+
<input id="product_price" max="20.0" min="1.0" name="product[price]" step="0.5" type="number" />
|
199
|
+
<input id="product_discount" max="100" min="1" name="product[discount]" type="range" />
|
193
200
|
```
|
194
201
|
|
195
202
|
Hidden inputs are not shown to the user but instead hold data like any textual input. Values inside them can be changed with JavaScript.
|
196
203
|
|
197
|
-
IMPORTANT: The search, telephone, date, time, color, datetime, datetime-local,
|
204
|
+
IMPORTANT: The search, telephone, date, time, color, datetime, datetime-local,
|
205
|
+
month, week, URL, email, number and range inputs are HTML5 controls.
|
206
|
+
If you require your app to have a consistent experience in older browsers,
|
207
|
+
you will need an HTML5 polyfill (provided by CSS and/or JavaScript).
|
208
|
+
There is definitely [no shortage of solutions for this](https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills), although a couple of popular tools at the moment are
|
209
|
+
[Modernizr](http://www.modernizr.com/) and [yepnope](http://yepnopejs.com/),
|
210
|
+
which provide a simple way to add functionality based on the presence of
|
211
|
+
detected HTML5 features.
|
198
212
|
|
199
213
|
TIP: If you're using password input fields (for any purpose), you might want to configure your application to prevent those parameters from being logged. You can learn about this in the [Security Guide](security.html#logging).
|
200
214
|
|
@@ -290,7 +304,7 @@ The object yielded by `fields_for` is a form builder like the one yielded by `fo
|
|
290
304
|
|
291
305
|
### Relying on Record Identification
|
292
306
|
|
293
|
-
The Article model is directly available to users of the application, so
|
307
|
+
The Article model is directly available to users of the application, so - following the best practices for developing with Rails - you should declare it **a resource**:
|
294
308
|
|
295
309
|
```ruby
|
296
310
|
resources :articles
|
@@ -328,7 +342,7 @@ If you have created namespaced routes, `form_for` has a nifty shorthand for that
|
|
328
342
|
form_for [:admin, @article]
|
329
343
|
```
|
330
344
|
|
331
|
-
will create a form that submits to the
|
345
|
+
will create a form that submits to the `ArticlesController` inside the admin namespace (submitting to `admin_article_path(@article)` in the case of an update). If you have several levels of namespacing then the syntax is similar:
|
332
346
|
|
333
347
|
```ruby
|
334
348
|
form_for [:admin, :management, @article]
|
@@ -381,7 +395,7 @@ Here you have a list of cities whose names are presented to the user. Internally
|
|
381
395
|
|
382
396
|
### The Select and Option Tags
|
383
397
|
|
384
|
-
The most generic helper is `select_tag`, which
|
398
|
+
The most generic helper is `select_tag`, which - as the name implies - simply generates the `SELECT` tag that encapsulates an options string:
|
385
399
|
|
386
400
|
```erb
|
387
401
|
<%= select_tag(:city_id, '<option value="1">Lisbon</option>...') %>
|
@@ -421,7 +435,7 @@ output:
|
|
421
435
|
|
422
436
|
Whenever Rails sees that the internal value of an option being generated matches this value, it will add the `selected` attribute to that option.
|
423
437
|
|
424
|
-
TIP: The second argument to `options_for_select` must be exactly equal to the desired internal value. In particular if the value is the integer 2 you cannot pass "2" to `options_for_select`
|
438
|
+
TIP: The second argument to `options_for_select` must be exactly equal to the desired internal value. In particular if the value is the integer 2 you cannot pass "2" to `options_for_select` - you must pass 2. Be aware of values extracted from the `params` hash as they are all strings.
|
425
439
|
|
426
440
|
WARNING: when `:include_blank` or `:prompt` are not present, `:include_blank` is forced true if the select attribute `required` is true, display `size` is one and `multiple` is not true.
|
427
441
|
|
@@ -451,7 +465,7 @@ In most cases form controls will be tied to a specific database model and as you
|
|
451
465
|
<%= select(:person, :city_id, [['Lisbon', 1], ['Madrid', 2], ...]) %>
|
452
466
|
```
|
453
467
|
|
454
|
-
Notice that the third parameter, the options array, is the same kind of argument you pass to `options_for_select`. One advantage here is that you don't have to worry about pre-selecting the correct city if the user already has one
|
468
|
+
Notice that the third parameter, the options array, is the same kind of argument you pass to `options_for_select`. One advantage here is that you don't have to worry about pre-selecting the correct city if the user already has one - Rails will do this for you by reading from the `@person.city_id` attribute.
|
455
469
|
|
456
470
|
As with other helpers, if you were to use the `select` helper on a form builder scoped to the `@person` object, the syntax would be:
|
457
471
|
|
@@ -553,7 +567,7 @@ outputs (with actual option values omitted for brevity)
|
|
553
567
|
which results in a `params` hash like
|
554
568
|
|
555
569
|
```ruby
|
556
|
-
{
|
570
|
+
{'person' => {'birth_date(1i)' => '2008', 'birth_date(2i)' => '11', 'birth_date(3i)' => '22'}}
|
557
571
|
```
|
558
572
|
|
559
573
|
When this is passed to `Person.new` (or `update`), Active Record spots that these parameters should all be used to construct the `birth_date` attribute and uses the suffixed information to determine in which order it should pass these parameters to functions such as `Date.civil`.
|
@@ -568,7 +582,7 @@ NOTE: In many cases the built-in date pickers are clumsy as they do not aid the
|
|
568
582
|
|
569
583
|
### Individual Components
|
570
584
|
|
571
|
-
Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component `select_year`, `select_month`, `select_day`, `select_hour`, `select_minute`, `select_second`. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for `select_year`, "month" for `select_month` etc.) although this can be overridden with the
|
585
|
+
Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component `select_year`, `select_month`, `select_day`, `select_hour`, `select_minute`, `select_second`. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for `select_year`, "month" for `select_month` etc.) although this can be overridden with the `:field_name` option. The `:prefix` option works in the same way that it does for `select_date` and `select_time` and has the same default value.
|
572
586
|
|
573
587
|
The first parameter specifies which value should be selected and can either be an instance of a Date, Time or DateTime, in which case the relevant component will be extracted, or a numerical value. For example
|
574
588
|
|
@@ -664,7 +678,7 @@ Understanding Parameter Naming Conventions
|
|
664
678
|
As you've seen in the previous sections, values from forms can be at the top level of the `params` hash or nested in another hash. For example in a standard `create`
|
665
679
|
action for a Person model, `params[:person]` would usually be a hash of all the attributes for the person to create. The `params` hash can also contain arrays, arrays of hashes and so on.
|
666
680
|
|
667
|
-
Fundamentally HTML forms don't know about any sort of structured data, all they generate is name
|
681
|
+
Fundamentally HTML forms don't know about any sort of structured data, all they generate is name-value pairs, where pairs are just plain strings. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses.
|
668
682
|
|
669
683
|
TIP: You may find you can try out examples in this section faster by using the console to directly invoke Racks' parameter parser. For example,
|
670
684
|
|
@@ -837,7 +851,7 @@ Many apps grow beyond simple forms editing a single object. For example when cre
|
|
837
851
|
|
838
852
|
### Configuring the Model
|
839
853
|
|
840
|
-
Active Record provides model level support
|
854
|
+
Active Record provides model level support via the `accepts_nested_attributes_for` method:
|
841
855
|
|
842
856
|
```ruby
|
843
857
|
class Person < ActiveRecord::Base
|
@@ -852,7 +866,7 @@ end
|
|
852
866
|
|
853
867
|
This creates an `addresses_attributes=` method on `Person` that allows you to create, update and (optionally) destroy addresses.
|
854
868
|
|
855
|
-
###
|
869
|
+
### Nested Forms
|
856
870
|
|
857
871
|
The following form allows a user to create a `Person` and its associated addresses.
|
858
872
|
|
@@ -875,38 +889,40 @@ The following form allows a user to create a `Person` and its associated address
|
|
875
889
|
```
|
876
890
|
|
877
891
|
|
878
|
-
When an association accepts nested attributes `fields_for` renders its block once for every element of the association. In particular, if a person has no addresses it renders nothing. A common pattern is for the controller to build one or more empty children so that at least one set of fields is shown to the user. The example below would result in
|
892
|
+
When an association accepts nested attributes `fields_for` renders its block once for every element of the association. In particular, if a person has no addresses it renders nothing. A common pattern is for the controller to build one or more empty children so that at least one set of fields is shown to the user. The example below would result in 2 sets of address fields being rendered on the new person form.
|
879
893
|
|
880
894
|
```ruby
|
881
895
|
def new
|
882
896
|
@person = Person.new
|
883
|
-
|
897
|
+
2.times { @person.addresses.build}
|
884
898
|
end
|
885
899
|
```
|
886
900
|
|
887
|
-
`fields_for` yields a form builder
|
901
|
+
The `fields_for` yields a form builder. The parameters' name will be what
|
902
|
+
`accepts_nested_attributes_for` expects. For example when creating a user with
|
903
|
+
2 addresses, the submitted parameters would look like:
|
888
904
|
|
889
905
|
```ruby
|
890
906
|
{
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
}
|
907
|
+
'person' => {
|
908
|
+
'name' => 'John Doe',
|
909
|
+
'addresses_attributes' => {
|
910
|
+
'0' => {
|
911
|
+
'kind' => 'Home',
|
912
|
+
'street' => '221b Baker Street'
|
913
|
+
},
|
914
|
+
'1' => {
|
915
|
+
'kind' => 'Office',
|
916
|
+
'street' => '31 Spooner Street'
|
917
|
+
}
|
903
918
|
}
|
919
|
+
}
|
904
920
|
}
|
905
921
|
```
|
906
922
|
|
907
923
|
The keys of the `:addresses_attributes` hash are unimportant, they need merely be different for each address.
|
908
924
|
|
909
|
-
If the associated object is already saved, `fields_for` autogenerates a hidden input with the `id` of the saved record. You can disable this by passing `include_id: false` to `fields_for`. You may wish to do this if the autogenerated input is placed in a location where an input tag is not valid HTML or when using an ORM where children do not have an id
|
925
|
+
If the associated object is already saved, `fields_for` autogenerates a hidden input with the `id` of the saved record. You can disable this by passing `include_id: false` to `fields_for`. You may wish to do this if the autogenerated input is placed in a location where an input tag is not valid HTML or when using an ORM where children do not have an `id`.
|
910
926
|
|
911
927
|
### The Controller
|
912
928
|
|
@@ -921,9 +937,9 @@ def create
|
|
921
937
|
end
|
922
938
|
|
923
939
|
private
|
924
|
-
def person_params
|
925
|
-
|
926
|
-
end
|
940
|
+
def person_params
|
941
|
+
params.require(:person).permit(:name, addresses_attributes: [:id, :kind, :street])
|
942
|
+
end
|
927
943
|
```
|
928
944
|
|
929
945
|
### Removing Objects
|
@@ -937,7 +953,9 @@ class Person < ActiveRecord::Base
|
|
937
953
|
end
|
938
954
|
```
|
939
955
|
|
940
|
-
If the hash of attributes for an object contains the key `_destroy` with a value
|
956
|
+
If the hash of attributes for an object contains the key `_destroy` with a value
|
957
|
+
of `1` or `true` then the object will be destroyed. This form allows users to
|
958
|
+
remove addresses:
|
941
959
|
|
942
960
|
```erb
|
943
961
|
<%= form_for @person do |f| %>
|
@@ -945,7 +963,7 @@ If the hash of attributes for an object contains the key `_destroy` with a value
|
|
945
963
|
<ul>
|
946
964
|
<%= f.fields_for :addresses do |addresses_form| %>
|
947
965
|
<li>
|
948
|
-
<%= check_box :_destroy%>
|
966
|
+
<%= addresses_form.check_box :_destroy%>
|
949
967
|
<%= addresses_form.label :kind %>
|
950
968
|
<%= addresses_form.text_field :kind %>
|
951
969
|
...
|
@@ -980,4 +998,4 @@ As a convenience you can instead pass the symbol `:all_blank` which will create
|
|
980
998
|
|
981
999
|
### Adding Fields on the Fly
|
982
1000
|
|
983
|
-
Rather than rendering multiple sets of fields ahead of time you may wish to add them only when a user clicks on an 'Add new
|
1001
|
+
Rather than rendering multiple sets of fields ahead of time you may wish to add them only when a user clicks on an 'Add new address' button. Rails does not provide any builtin support for this. When generating new sets of fields you must ensure the key of the associated array is unique - the current JavaScript date (milliseconds after the epoch) is a common choice.
|
data/guides/source/generators.md
CHANGED
@@ -23,13 +23,13 @@ When you create an application using the `rails` command, you are in fact using
|
|
23
23
|
```bash
|
24
24
|
$ rails new myapp
|
25
25
|
$ cd myapp
|
26
|
-
$ rails generate
|
26
|
+
$ bin/rails generate
|
27
27
|
```
|
28
28
|
|
29
29
|
You will get a list of all generators that comes with Rails. If you need a detailed description of the helper generator, for example, you can simply do:
|
30
30
|
|
31
31
|
```bash
|
32
|
-
$ rails generate helper --help
|
32
|
+
$ bin/rails generate helper --help
|
33
33
|
```
|
34
34
|
|
35
35
|
Creating Your First Generator
|
@@ -54,13 +54,13 @@ Our new generator is quite simple: it inherits from `Rails::Generators::Base` an
|
|
54
54
|
To invoke our new generator, we just need to do:
|
55
55
|
|
56
56
|
```bash
|
57
|
-
$ rails generate initializer
|
57
|
+
$ bin/rails generate initializer
|
58
58
|
```
|
59
59
|
|
60
60
|
Before we go on, let's see our brand new generator description:
|
61
61
|
|
62
62
|
```bash
|
63
|
-
$ rails generate initializer --help
|
63
|
+
$ bin/rails generate initializer --help
|
64
64
|
```
|
65
65
|
|
66
66
|
Rails is usually able to generate good descriptions if a generator is namespaced, as `ActiveRecord::Generators::ModelGenerator`, but not in this particular case. We can solve this problem in two ways. The first one is calling `desc` inside our generator:
|
@@ -82,7 +82,7 @@ Creating Generators with Generators
|
|
82
82
|
Generators themselves have a generator:
|
83
83
|
|
84
84
|
```bash
|
85
|
-
$ rails generate generator initializer
|
85
|
+
$ bin/rails generate generator initializer
|
86
86
|
create lib/generators/initializer
|
87
87
|
create lib/generators/initializer/initializer_generator.rb
|
88
88
|
create lib/generators/initializer/USAGE
|
@@ -102,7 +102,7 @@ First, notice that we are inheriting from `Rails::Generators::NamedBase` instead
|
|
102
102
|
We can see that by invoking the description of this new generator (don't forget to delete the old generator file):
|
103
103
|
|
104
104
|
```bash
|
105
|
-
$ rails generate initializer --help
|
105
|
+
$ bin/rails generate initializer --help
|
106
106
|
Usage:
|
107
107
|
rails generate initializer NAME [options]
|
108
108
|
```
|
@@ -130,7 +130,7 @@ end
|
|
130
130
|
And let's execute our generator:
|
131
131
|
|
132
132
|
```bash
|
133
|
-
$ rails generate initializer core_extensions
|
133
|
+
$ bin/rails generate initializer core_extensions
|
134
134
|
```
|
135
135
|
|
136
136
|
We can see that now an 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`.
|
@@ -169,7 +169,7 @@ end
|
|
169
169
|
Before we customize our workflow, let's first see what our scaffold looks like:
|
170
170
|
|
171
171
|
```bash
|
172
|
-
$ rails generate scaffold User name:string
|
172
|
+
$ bin/rails generate scaffold User name:string
|
173
173
|
invoke active_record
|
174
174
|
create db/migrate/20130924151154_create_users.rb
|
175
175
|
create app/models/user.rb
|
@@ -207,7 +207,7 @@ $ rails generate scaffold User name:string
|
|
207
207
|
|
208
208
|
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.
|
209
209
|
|
210
|
-
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:
|
210
|
+
Our first customization on the workflow will be to stop generating stylesheets, javascripts and test fixtures for scaffolds. We can achieve that by changing our configuration to the following:
|
211
211
|
|
212
212
|
```ruby
|
213
213
|
config.generators do |g|
|
@@ -215,15 +215,16 @@ config.generators do |g|
|
|
215
215
|
g.template_engine :erb
|
216
216
|
g.test_framework :test_unit, fixture: false
|
217
217
|
g.stylesheets false
|
218
|
+
g.javascripts false
|
218
219
|
end
|
219
220
|
```
|
220
221
|
|
221
|
-
If we generate another resource with the scaffold generator, we can see that
|
222
|
+
If we generate another resource with the scaffold generator, we can see that stylesheets, javascripts and fixtures are not 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.
|
222
223
|
|
223
224
|
To demonstrate this, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator within the rails namespace, as this is where rails searches for generators used as hooks:
|
224
225
|
|
225
226
|
```bash
|
226
|
-
$ rails generate generator rails/my_helper
|
227
|
+
$ bin/rails generate generator rails/my_helper
|
227
228
|
create lib/generators/rails/my_helper
|
228
229
|
create lib/generators/rails/my_helper/my_helper_generator.rb
|
229
230
|
create lib/generators/rails/my_helper/USAGE
|
@@ -250,7 +251,7 @@ end
|
|
250
251
|
We can try out our new generator by creating a helper for users:
|
251
252
|
|
252
253
|
```bash
|
253
|
-
$ rails generate my_helper products
|
254
|
+
$ bin/rails generate my_helper products
|
254
255
|
create app/helpers/products_helper.rb
|
255
256
|
```
|
256
257
|
|
@@ -270,6 +271,7 @@ config.generators do |g|
|
|
270
271
|
g.template_engine :erb
|
271
272
|
g.test_framework :test_unit, fixture: false
|
272
273
|
g.stylesheets false
|
274
|
+
g.javascripts false
|
273
275
|
g.helper :my_helper
|
274
276
|
end
|
275
277
|
```
|
@@ -277,7 +279,7 @@ end
|
|
277
279
|
and see it in action when invoking the generator:
|
278
280
|
|
279
281
|
```bash
|
280
|
-
$ rails generate scaffold Post body:text
|
282
|
+
$ bin/rails generate scaffold Post body:text
|
281
283
|
[...]
|
282
284
|
invoke my_helper
|
283
285
|
create app/helpers/posts_helper.rb
|
@@ -334,6 +336,7 @@ config.generators do |g|
|
|
334
336
|
g.template_engine :erb
|
335
337
|
g.test_framework :test_unit, fixture: false
|
336
338
|
g.stylesheets false
|
339
|
+
g.javascripts false
|
337
340
|
end
|
338
341
|
```
|
339
342
|
|
@@ -352,6 +355,7 @@ config.generators do |g|
|
|
352
355
|
g.template_engine :erb
|
353
356
|
g.test_framework :shoulda, fixture: false
|
354
357
|
g.stylesheets false
|
358
|
+
g.javascripts false
|
355
359
|
|
356
360
|
# Add a fallback!
|
357
361
|
g.fallbacks[:shoulda] = :test_unit
|
@@ -361,7 +365,7 @@ end
|
|
361
365
|
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:
|
362
366
|
|
363
367
|
```bash
|
364
|
-
$ rails generate scaffold Comment body:text
|
368
|
+
$ bin/rails generate scaffold Comment body:text
|
365
369
|
invoke active_record
|
366
370
|
create db/migrate/20130924143118_create_comments.rb
|
367
371
|
create app/models/comment.rb
|
@@ -556,7 +560,7 @@ This method also takes a block:
|
|
556
560
|
|
557
561
|
```ruby
|
558
562
|
vendor "seeds.rb" do
|
559
|
-
"puts 'in
|
563
|
+
"puts 'in your app, seeding your database'"
|
560
564
|
end
|
561
565
|
```
|
562
566
|
|