rails 4.0.13 → 4.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +20 -15
- data/guides/CHANGELOG.md +5 -74
- 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/challenge.png +0 -0
- 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/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/template_is_missing_posts_new.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/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 +2 -0
- data/guides/bug_report_templates/action_controller_master.rb +2 -0
- data/guides/bug_report_templates/active_record_gem.rb +1 -1
- data/guides/bug_report_templates/active_record_master.rb +2 -1
- data/guides/code/getting_started/Gemfile +1 -1
- data/guides/code/getting_started/app/assets/javascripts/application.js +1 -2
- data/guides/code/getting_started/config/environments/development.rb +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/rails_guides/helpers.rb +1 -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 +1 -2
- data/guides/source/3_1_release_notes.md +1 -1
- 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 +601 -0
- data/guides/source/_welcome.html.erb +1 -1
- data/guides/source/action_controller_overview.md +117 -31
- data/guides/source/action_mailer_basics.md +19 -19
- data/guides/source/action_view_overview.md +131 -12
- 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 +67 -39
- data/guides/source/active_record_validations.md +31 -31
- data/guides/source/active_support_core_extensions.md +63 -74
- data/guides/source/active_support_instrumentation.md +13 -4
- data/guides/source/api_documentation_guidelines.md +19 -5
- data/guides/source/asset_pipeline.md +544 -249
- data/guides/source/association_basics.md +81 -22
- data/guides/source/caching_with_rails.md +15 -6
- data/guides/source/command_line.md +28 -19
- data/guides/source/configuring.md +98 -50
- data/guides/source/contributing_to_ruby_on_rails.md +11 -11
- data/guides/source/credits.html.erb +2 -2
- data/guides/source/debugging_rails_applications.md +36 -5
- data/guides/source/development_dependencies_install.md +89 -8
- data/guides/source/documents.yaml +7 -1
- data/guides/source/engines.md +648 -224
- data/guides/source/form_helpers.md +56 -45
- data/guides/source/generators.md +7 -3
- data/guides/source/getting_started.md +379 -164
- data/guides/source/i18n.md +59 -23
- data/guides/source/index.html.erb +1 -1
- data/guides/source/initialization.md +153 -56
- data/guides/source/kindle/toc.html.erb +1 -1
- data/guides/source/layout.html.erb +3 -3
- data/guides/source/layouts_and_rendering.md +12 -11
- data/guides/source/maintenance_policy.md +4 -23
- data/guides/source/migrations.md +41 -37
- data/guides/source/nested_model_forms.md +3 -3
- data/guides/source/plugins.md +27 -23
- data/guides/source/rails_application_templates.md +25 -6
- data/guides/source/rails_on_rack.md +35 -51
- data/guides/source/routing.md +108 -99
- data/guides/source/ruby_on_rails_guides_guidelines.md +2 -2
- data/guides/source/security.md +33 -31
- data/guides/source/testing.md +37 -34
- data/guides/source/upgrading_ruby_on_rails.md +335 -16
- data/guides/source/working_with_javascript_in_rails.md +18 -10
- metadata +66 -39
- 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
|
|
@@ -737,7 +751,7 @@ You might want to render a form with a set of edit fields for each of a person's
|
|
737
751
|
<%= form_for @person do |person_form| %>
|
738
752
|
<%= person_form.text_field :name %>
|
739
753
|
<% @person.addresses.each do |address| %>
|
740
|
-
<%= person_form.fields_for address, index: address
|
754
|
+
<%= person_form.fields_for address, index: address do |address_form|%>
|
741
755
|
<%= address_form.text_field :city %>
|
742
756
|
<% end %>
|
743
757
|
<% end %>
|
@@ -760,16 +774,9 @@ This will result in a `params` hash that looks like
|
|
760
774
|
{'person' => {'name' => 'Bob', 'address' => {'23' => {'city' => 'Paris'}, '45' => {'city' => 'London'}}}}
|
761
775
|
```
|
762
776
|
|
763
|
-
Rails knows that all these inputs should be part of the person hash because you
|
764
|
-
called `fields_for` on the first form builder. By specifying an `:index` option
|
765
|
-
you're telling Rails that instead of naming the inputs `person[address][city]`
|
766
|
-
it should insert that index surrounded by [] between the address and the city.
|
767
|
-
This is often useful as it is then easy to locate which Address record
|
768
|
-
should be modified. You can pass numbers with some other significance,
|
769
|
-
strings or even `nil` (which will result in an array parameter being created).
|
777
|
+
Rails knows that all these inputs should be part of the person hash because you called `fields_for` on the first form builder. By specifying an `:index` option you're telling Rails that instead of naming the inputs `person[address][city]` it should insert that index surrounded by [] between the address and the city. If you pass an Active Record object as we did then Rails will call `to_param` on it, which by default returns the database id. This is often useful as it is then easy to locate which Address record should be modified. You can pass numbers with some other significance, strings or even `nil` (which will result in an array parameter being created).
|
770
778
|
|
771
|
-
To create more intricate nestings, you can specify the first part of the input
|
772
|
-
name (`person[address]` in the previous example) explicitly:
|
779
|
+
To create more intricate nestings, you can specify the first part of the input name (`person[address]` in the previous example) explicitly, for example
|
773
780
|
|
774
781
|
```erb
|
775
782
|
<%= fields_for 'person[address][primary]', address, index: address do |address_form| %>
|
@@ -837,7 +844,7 @@ Many apps grow beyond simple forms editing a single object. For example when cre
|
|
837
844
|
|
838
845
|
### Configuring the Model
|
839
846
|
|
840
|
-
Active Record provides model level support
|
847
|
+
Active Record provides model level support via the `accepts_nested_attributes_for` method:
|
841
848
|
|
842
849
|
```ruby
|
843
850
|
class Person < ActiveRecord::Base
|
@@ -852,7 +859,7 @@ end
|
|
852
859
|
|
853
860
|
This creates an `addresses_attributes=` method on `Person` that allows you to create, update and (optionally) destroy addresses.
|
854
861
|
|
855
|
-
###
|
862
|
+
### Nested Forms
|
856
863
|
|
857
864
|
The following form allows a user to create a `Person` and its associated addresses.
|
858
865
|
|
@@ -875,38 +882,40 @@ The following form allows a user to create a `Person` and its associated address
|
|
875
882
|
```
|
876
883
|
|
877
884
|
|
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
|
885
|
+
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
886
|
|
880
887
|
```ruby
|
881
888
|
def new
|
882
889
|
@person = Person.new
|
883
|
-
|
890
|
+
2.times { @person.addresses.build}
|
884
891
|
end
|
885
892
|
```
|
886
893
|
|
887
|
-
`fields_for` yields a form builder
|
894
|
+
The `fields_for` yields a form builder. The parameters' name will be what
|
895
|
+
`accepts_nested_attributes_for` expects. For example when creating a user with
|
896
|
+
2 addresses, the submitted parameters would look like:
|
888
897
|
|
889
898
|
```ruby
|
890
899
|
{
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
}
|
900
|
+
'person' => {
|
901
|
+
'name' => 'John Doe',
|
902
|
+
'addresses_attributes' => {
|
903
|
+
'0' => {
|
904
|
+
'kind' => 'Home',
|
905
|
+
'street' => '221b Baker Street'
|
906
|
+
},
|
907
|
+
'1' => {
|
908
|
+
'kind' => 'Office',
|
909
|
+
'street' => '31 Spooner Street'
|
910
|
+
}
|
903
911
|
}
|
912
|
+
}
|
904
913
|
}
|
905
914
|
```
|
906
915
|
|
907
916
|
The keys of the `:addresses_attributes` hash are unimportant, they need merely be different for each address.
|
908
917
|
|
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
|
918
|
+
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
919
|
|
911
920
|
### The Controller
|
912
921
|
|
@@ -921,9 +930,9 @@ def create
|
|
921
930
|
end
|
922
931
|
|
923
932
|
private
|
924
|
-
def person_params
|
925
|
-
|
926
|
-
end
|
933
|
+
def person_params
|
934
|
+
params.require(:person).permit(:name, addresses_attributes: [:id, :kind, :street])
|
935
|
+
end
|
927
936
|
```
|
928
937
|
|
929
938
|
### Removing Objects
|
@@ -937,7 +946,9 @@ class Person < ActiveRecord::Base
|
|
937
946
|
end
|
938
947
|
```
|
939
948
|
|
940
|
-
If the hash of attributes for an object contains the key `_destroy` with a value
|
949
|
+
If the hash of attributes for an object contains the key `_destroy` with a value
|
950
|
+
of `1` or `true` then the object will be destroyed. This form allows users to
|
951
|
+
remove addresses:
|
941
952
|
|
942
953
|
```erb
|
943
954
|
<%= form_for @person do |f| %>
|
@@ -945,7 +956,7 @@ If the hash of attributes for an object contains the key `_destroy` with a value
|
|
945
956
|
<ul>
|
946
957
|
<%= f.fields_for :addresses do |addresses_form| %>
|
947
958
|
<li>
|
948
|
-
<%= check_box :_destroy%>
|
959
|
+
<%= addresses_form.check_box :_destroy%>
|
949
960
|
<%= addresses_form.label :kind %>
|
950
961
|
<%= addresses_form.text_field :kind %>
|
951
962
|
...
|
@@ -980,4 +991,4 @@ As a convenience you can instead pass the symbol `:all_blank` which will create
|
|
980
991
|
|
981
992
|
### Adding Fields on the Fly
|
982
993
|
|
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
|
994
|
+
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
@@ -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,10 +215,11 @@ 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
|
|
@@ -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
|
```
|
@@ -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
|
@@ -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
|
|
@@ -22,14 +22,14 @@ with Rails. However, to get the most out of it, you need to have some
|
|
22
22
|
prerequisites installed:
|
23
23
|
|
24
24
|
* The [Ruby](http://www.ruby-lang.org/en/downloads) language version 1.9.3 or newer
|
25
|
-
* The [RubyGems](http://rubygems.org
|
26
|
-
* To learn more about RubyGems, please read the [RubyGems
|
25
|
+
* The [RubyGems](http://rubygems.org) packaging system
|
26
|
+
* To learn more about RubyGems, please read the [RubyGems Guides](http://guides.rubygems.org)
|
27
27
|
* A working installation of the [SQLite3 Database](http://www.sqlite.org)
|
28
28
|
|
29
29
|
Rails is a web application framework running on the Ruby programming language.
|
30
30
|
If you have no prior experience with Ruby, you will find a very steep learning
|
31
31
|
curve diving straight into Rails. There are some good free resources on the
|
32
|
-
|
32
|
+
Internet for learning Ruby, including:
|
33
33
|
|
34
34
|
* [Mr. Neighborly's Humble Little Ruby Book](http://www.humblelittlerubybook.com)
|
35
35
|
* [Programming Ruby](http://www.ruby-doc.org/docs/ProgrammingRuby/)
|
@@ -54,16 +54,19 @@ learned elsewhere, you may have a less happy experience.
|
|
54
54
|
|
55
55
|
The Rails philosophy includes two major guiding principles:
|
56
56
|
|
57
|
-
* DRY - "Don't Repeat Yourself" - suggests that writing the same code over and
|
58
|
-
|
59
|
-
|
57
|
+
* DRY - "Don't Repeat Yourself" - suggests that writing the same code over and
|
58
|
+
over again is a bad thing.
|
59
|
+
* Convention Over Configuration - means that Rails makes assumptions about what
|
60
|
+
you want to do and how you're going to do it, rather than requiring you to
|
61
|
+
specify every little thing through endless configuration files.
|
60
62
|
|
61
63
|
Creating a New Rails Project
|
62
64
|
----------------------------
|
63
65
|
|
64
66
|
The best way to use this guide is to follow each step as it happens, no code or
|
65
67
|
step needed to make this example application has been left out, so you can
|
66
|
-
literally follow along step by step.
|
68
|
+
literally follow along step by step. You can get the complete code
|
69
|
+
[here](https://github.com/rails/docrails/tree/master/guides/code/getting_started).
|
67
70
|
|
68
71
|
By following along with this guide, you'll create a Rails project called
|
69
72
|
`blog`, a
|
@@ -83,7 +86,7 @@ current version of Ruby installed:
|
|
83
86
|
|
84
87
|
```bash
|
85
88
|
$ ruby -v
|
86
|
-
ruby
|
89
|
+
ruby 2.0.0p247
|
87
90
|
```
|
88
91
|
|
89
92
|
To install Rails, use the `gem install` command provided by RubyGems:
|
@@ -93,10 +96,11 @@ $ gem install rails
|
|
93
96
|
```
|
94
97
|
|
95
98
|
TIP. A number of tools exist to help you quickly install Ruby and Ruby
|
96
|
-
on Rails on your system. Windows users can use [Rails Installer](http://railsinstaller.org),
|
97
|
-
[Rails One Click](http://railsoneclick.com).
|
99
|
+
on Rails on your system. Windows users can use [Rails Installer](http://railsinstaller.org),
|
100
|
+
while Mac OS X users can use [Rails One Click](http://railsoneclick.com).
|
98
101
|
|
99
|
-
To verify that you have everything installed correctly, you should be able to
|
102
|
+
To verify that you have everything installed correctly, you should be able to
|
103
|
+
run the following:
|
100
104
|
|
101
105
|
```bash
|
102
106
|
$ rails --version
|
@@ -106,38 +110,47 @@ If it says something like "Rails 4.0.0", you are ready to continue.
|
|
106
110
|
|
107
111
|
### Creating the Blog Application
|
108
112
|
|
109
|
-
Rails comes with a number of scripts called generators that are designed to make
|
113
|
+
Rails comes with a number of scripts called generators that are designed to make
|
114
|
+
your development life easier by creating everything that's necessary to start
|
115
|
+
working on a particular task. One of these is the new application generator,
|
116
|
+
which will provide you with the foundation of a fresh Rails application so that
|
117
|
+
you don't have to write it yourself.
|
110
118
|
|
111
|
-
To use this generator, open a terminal, navigate to a directory where you have
|
119
|
+
To use this generator, open a terminal, navigate to a directory where you have
|
120
|
+
rights to create files, and type:
|
112
121
|
|
113
122
|
```bash
|
114
123
|
$ rails new blog
|
115
124
|
```
|
116
125
|
|
117
|
-
This will create a Rails application called Blog in a directory called blog and
|
126
|
+
This will create a Rails application called Blog in a directory called blog and
|
127
|
+
install the gem dependencies that are already mentioned in `Gemfile` using
|
128
|
+
`bundle install`.
|
118
129
|
|
119
|
-
TIP: You can see all of the command line options that the Rails
|
120
|
-
|
130
|
+
TIP: You can see all of the command line options that the Rails application
|
131
|
+
builder accepts by running `rails new -h`.
|
121
132
|
|
122
|
-
After you create the blog application, switch to its folder to continue work
|
133
|
+
After you create the blog application, switch to its folder to continue work
|
134
|
+
directly in that application:
|
123
135
|
|
124
136
|
```bash
|
125
137
|
$ cd blog
|
126
138
|
```
|
127
139
|
|
128
|
-
The `rails new blog` command we ran above created a folder in your
|
129
|
-
|
130
|
-
|
131
|
-
|
140
|
+
The `rails new blog` command we ran above created a folder in your working
|
141
|
+
directory called `blog`. The `blog` directory has a number of auto-generated
|
142
|
+
files and folders that make up the structure of a Rails application. Most of the
|
143
|
+
work in this tutorial will happen in the `app/` folder, but here's a basic
|
144
|
+
rundown on the function of each of the files and folders that Rails created by default:
|
132
145
|
|
133
146
|
| File/Folder | Purpose |
|
134
147
|
| ----------- | ------- |
|
135
148
|
|app/|Contains the controllers, models, views, helpers, mailers and assets for your application. You'll focus on this folder for the remainder of this guide.|
|
136
149
|
|bin/|Contains the rails script that starts your app and can contain other scripts you use to deploy or run your application.|
|
137
|
-
|config/|Configure your application's runtime rules, routes, database, and more.
|
150
|
+
|config/|Configure your application's runtime rules, routes, database, and more. This is covered in more detail in [Configuring Rails Applications](configuring.html)|
|
138
151
|
|config.ru|Rack configuration for Rack based servers used to start the application.|
|
139
152
|
|db/|Contains your current database schema, as well as the database migrations.|
|
140
|
-
|Gemfile<br
|
153
|
+
|Gemfile<br>Gemfile.lock|These files allow you to specify what gem dependencies are needed for your Rails application. These files are used by the Bundler gem. For more information about Bundler, see [the Bundler website](http://gembundler.com) |
|
141
154
|
|lib/|Extended modules for your application.|
|
142
155
|
|log/|Application log files.|
|
143
156
|
|public/|The only folder seen to the world as-is. Contains the static files and compiled assets.|
|
@@ -150,35 +163,65 @@ application. Most of the work in this tutorial will happen in the `app/` folder,
|
|
150
163
|
Hello, Rails!
|
151
164
|
-------------
|
152
165
|
|
153
|
-
To begin with, let's get some text up on screen quickly. To do this, you need to
|
166
|
+
To begin with, let's get some text up on screen quickly. To do this, you need to
|
167
|
+
get your Rails application server running.
|
154
168
|
|
155
169
|
### Starting up the Web Server
|
156
170
|
|
157
|
-
You actually have a functional Rails application already. To see it, you need to
|
171
|
+
You actually have a functional Rails application already. To see it, you need to
|
172
|
+
start a web server on your development machine. You can do this by running the
|
173
|
+
following in the root directory of your rails application:
|
158
174
|
|
159
175
|
```bash
|
160
176
|
$ rails server
|
161
177
|
```
|
162
178
|
|
163
|
-
TIP: Compiling CoffeeScript to JavaScript requires a JavaScript runtime and the
|
179
|
+
TIP: Compiling CoffeeScript to JavaScript requires a JavaScript runtime and the
|
180
|
+
absence of a runtime will give you an `execjs` error. Usually Mac OS X and
|
181
|
+
Windows come with a JavaScript runtime installed. Rails adds the `therubyracer`
|
182
|
+
gem to Gemfile in a commented line for new apps and you can uncomment if you
|
183
|
+
need it. `therubyrhino` is the recommended runtime for JRuby users and is added
|
184
|
+
by default to Gemfile in apps generated under JRuby. You can investigate about
|
185
|
+
all the supported runtimes at [ExecJS](https://github.com/sstephenson/execjs#readme).
|
164
186
|
|
165
|
-
This will fire up WEBrick, a webserver built into Ruby by default. To see your
|
187
|
+
This will fire up WEBrick, a webserver built into Ruby by default. To see your
|
188
|
+
application in action, open a browser window and navigate to <http://localhost:3000>.
|
189
|
+
You should see the Rails default information page:
|
166
190
|
|
167
191
|
![Welcome Aboard screenshot](images/getting_started/rails_welcome.png)
|
168
192
|
|
169
|
-
TIP: To stop the web server, hit Ctrl+C in the terminal window where it's
|
193
|
+
TIP: To stop the web server, hit Ctrl+C in the terminal window where it's
|
194
|
+
running. To verify the server has stopped you should see your command prompt
|
195
|
+
cursor again. For most UNIX-like systems including Mac OS X this will be a
|
196
|
+
dollar sign `$`. In development mode, Rails does not generally require you to
|
197
|
+
restart the server; changes you make in files will be automatically picked up by
|
198
|
+
the server.
|
170
199
|
|
171
|
-
The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it
|
200
|
+
The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it
|
201
|
+
makes sure that you have your software configured correctly enough to serve a
|
202
|
+
page. You can also click on the _About your application's environment_ link to
|
203
|
+
see a summary of your application's environment.
|
172
204
|
|
173
205
|
### Say "Hello", Rails
|
174
206
|
|
175
|
-
To get Rails saying "Hello", you need to create at minimum a _controller_ and a
|
207
|
+
To get Rails saying "Hello", you need to create at minimum a _controller_ and a
|
208
|
+
_view_.
|
176
209
|
|
177
|
-
A controller's purpose is to receive specific requests for the application.
|
210
|
+
A controller's purpose is to receive specific requests for the application.
|
211
|
+
_Routing_ decides which controller receives which requests. Often, there is more
|
212
|
+
than one route to each controller, and different routes can be served by
|
213
|
+
different _actions_. Each action's purpose is to collect information to provide
|
214
|
+
it to a view.
|
178
215
|
|
179
|
-
A view's purpose is to display this information in a human readable format. An
|
216
|
+
A view's purpose is to display this information in a human readable format. An
|
217
|
+
important distinction to make is that it is the _controller_, not the view,
|
218
|
+
where information is collected. The view should just display that information.
|
219
|
+
By default, view templates are written in a language called ERB (Embedded Ruby)
|
220
|
+
which is converted by the request cycle in Rails before being sent to the user.
|
180
221
|
|
181
|
-
To create a new controller, you will need to run the "controller" generator and
|
222
|
+
To create a new controller, you will need to run the "controller" generator and
|
223
|
+
tell it you want a controller called "welcome" with an action called "index",
|
224
|
+
just like this:
|
182
225
|
|
183
226
|
```bash
|
184
227
|
$ rails generate controller welcome index
|
@@ -205,9 +248,12 @@ invoke scss
|
|
205
248
|
create app/assets/stylesheets/welcome.css.scss
|
206
249
|
```
|
207
250
|
|
208
|
-
Most important of these are of course the controller, located at `app/controllers/welcome_controller.rb`
|
251
|
+
Most important of these are of course the controller, located at `app/controllers/welcome_controller.rb`
|
252
|
+
and the view, located at `app/views/welcome/index.html.erb`.
|
209
253
|
|
210
|
-
Open the `app/views/welcome/index.html.erb` file in your text editor. Delete all
|
254
|
+
Open the `app/views/welcome/index.html.erb` file in your text editor. Delete all
|
255
|
+
of the existing code in the file, and replace it with the following single line
|
256
|
+
of code:
|
211
257
|
|
212
258
|
```html
|
213
259
|
<h1>Hello, Rails!</h1>
|
@@ -215,7 +261,10 @@ Open the `app/views/welcome/index.html.erb` file in your text editor. Delete all
|
|
215
261
|
|
216
262
|
### Setting the Application Home Page
|
217
263
|
|
218
|
-
Now that we have made the controller and view, we need to tell Rails when we
|
264
|
+
Now that we have made the controller and view, we need to tell Rails when we
|
265
|
+
want `Hello, Rails!` to show up. In our case, we want it to show up when we
|
266
|
+
navigate to the root URL of our site, <http://localhost:3000>. At the moment,
|
267
|
+
"Welcome Aboard" is occupying that spot.
|
219
268
|
|
220
269
|
Next, you have to tell Rails where your actual home page is located.
|
221
270
|
|
@@ -229,45 +278,65 @@ Blog::Application.routes.draw do
|
|
229
278
|
# first created -> highest priority.
|
230
279
|
# ...
|
231
280
|
# You can have the root of your site routed with "root"
|
232
|
-
# root
|
281
|
+
# root "welcome#index"
|
233
282
|
```
|
234
283
|
|
235
|
-
This is your application's _routing file_ which holds entries in a special DSL
|
284
|
+
This is your application's _routing file_ which holds entries in a special DSL
|
285
|
+
(domain-specific language) that tells Rails how to connect incoming requests to
|
286
|
+
controllers and actions. This file contains many sample routes on commented
|
287
|
+
lines, and one of them actually shows you how to connect the root of your site
|
288
|
+
to a specific controller and action. Find the line beginning with `root` and
|
289
|
+
uncomment it. It should look something like the following:
|
236
290
|
|
237
291
|
```ruby
|
238
292
|
root "welcome#index"
|
239
293
|
```
|
240
294
|
|
241
|
-
The `root "welcome#index"` tells Rails to map requests to the root of the
|
295
|
+
The `root "welcome#index"` tells Rails to map requests to the root of the
|
296
|
+
application to the welcome controller's index action and `get "welcome/index"`
|
297
|
+
tells Rails to map requests to <http://localhost:3000/welcome/index> to the
|
298
|
+
welcome controller's index action. This was created earlier when you ran the
|
299
|
+
controller generator (`rails generate controller welcome index`).
|
242
300
|
|
243
|
-
If you navigate to <http://localhost:3000> in your browser, you'll see the
|
301
|
+
If you navigate to <http://localhost:3000> in your browser, you'll see the
|
302
|
+
`Hello, Rails!` message you put into `app/views/welcome/index.html.erb`,
|
303
|
+
indicating that this new route is indeed going to `WelcomeController`'s `index`
|
304
|
+
action and is rendering the view correctly.
|
244
305
|
|
245
306
|
TIP: For more information about routing, refer to [Rails Routing from the Outside In](routing.html).
|
246
307
|
|
247
308
|
Getting Up and Running
|
248
309
|
----------------------
|
249
310
|
|
250
|
-
Now that you've seen how to create a controller, an action and a view, let's
|
311
|
+
Now that you've seen how to create a controller, an action and a view, let's
|
312
|
+
create something with a bit more substance.
|
251
313
|
|
252
|
-
In the Blog application, you will now create a new _resource_. A resource is the
|
314
|
+
In the Blog application, you will now create a new _resource_. A resource is the
|
315
|
+
term used for a collection of similar objects, such as posts, people or animals.
|
316
|
+
You can create, read, update and destroy items for a resource and these
|
317
|
+
operations are referred to as _CRUD_ operations.
|
253
318
|
|
254
|
-
Rails provides a `resources` method which can be used to declare a
|
255
|
-
|
319
|
+
Rails provides a `resources` method which can be used to declare a standard REST
|
320
|
+
resource. Here's what `config/routes.rb` should look like after the _post resource_
|
321
|
+
is declared.
|
256
322
|
|
257
323
|
```ruby
|
258
324
|
Blog::Application.routes.draw do
|
259
325
|
|
260
326
|
resources :posts
|
261
327
|
|
262
|
-
root
|
328
|
+
root "welcome#index"
|
263
329
|
end
|
264
330
|
```
|
265
331
|
|
266
|
-
If you run `rake routes`, you'll see that
|
267
|
-
standard RESTful actions.
|
332
|
+
If you run `rake routes`, you'll see that it has defined routes for all the
|
333
|
+
standard RESTful actions. The meaning of the prefix column (and other columns)
|
334
|
+
will be seen later, but for now notice that Rails has inferred the
|
335
|
+
singular form `post` and makes meaningful use of the distinction.
|
268
336
|
|
269
337
|
```bash
|
270
338
|
$ rake routes
|
339
|
+
Prefix Verb URI Pattern Controller#Action
|
271
340
|
posts GET /posts(.:format) posts#index
|
272
341
|
POST /posts(.:format) posts#create
|
273
342
|
new_post GET /posts/new(.:format) posts#new
|
@@ -279,32 +348,45 @@ edit_post GET /posts/:id/edit(.:format) posts#edit
|
|
279
348
|
root / welcome#index
|
280
349
|
```
|
281
350
|
|
282
|
-
In the next section, you will add the ability to create new posts in your
|
351
|
+
In the next section, you will add the ability to create new posts in your
|
352
|
+
application and be able to view them. This is the "C" and the "R" from CRUD:
|
353
|
+
creation and reading. The form for doing this will look like this:
|
283
354
|
|
284
355
|
![The new post form](images/getting_started/new_post.png)
|
285
356
|
|
286
|
-
It will look a little basic for now, but that's ok. We'll look at improving the
|
357
|
+
It will look a little basic for now, but that's ok. We'll look at improving the
|
358
|
+
styling for it afterwards.
|
287
359
|
|
288
360
|
### Laying down the ground work
|
289
361
|
|
290
|
-
The first thing that you are going to need to create a new post within the
|
362
|
+
The first thing that you are going to need to create a new post within the
|
363
|
+
application is a place to do that. A great place for that would be at `/posts/new`.
|
364
|
+
With the route already defined, requests can now be made to `/posts/new` in the
|
365
|
+
application. Navigate to <http://localhost:3000/posts/new> and you'll see a
|
366
|
+
routing error:
|
291
367
|
|
292
368
|
![Another routing error, uninitialized constant PostsController](images/getting_started/routing_error_no_controller.png)
|
293
369
|
|
294
|
-
This error occurs because the route needs to have a controller defined in order
|
370
|
+
This error occurs because the route needs to have a controller defined in order
|
371
|
+
to serve the request. The solution to this particular problem is simple: create
|
372
|
+
a controller called `PostsController`. You can do this by running this command:
|
295
373
|
|
296
374
|
```bash
|
297
375
|
$ rails g controller posts
|
298
376
|
```
|
299
377
|
|
300
|
-
If you open up the newly generated `app/controllers/posts_controller.rb` you'll
|
378
|
+
If you open up the newly generated `app/controllers/posts_controller.rb` you'll
|
379
|
+
see a fairly empty controller:
|
301
380
|
|
302
381
|
```ruby
|
303
382
|
class PostsController < ApplicationController
|
304
383
|
end
|
305
384
|
```
|
306
385
|
|
307
|
-
A controller is simply a class that is defined to inherit from `ApplicationController`.
|
386
|
+
A controller is simply a class that is defined to inherit from `ApplicationController`.
|
387
|
+
It's inside this class that you'll define methods that will become the actions
|
388
|
+
for this controller. These actions will perform CRUD operations on the posts
|
389
|
+
within our system.
|
308
390
|
|
309
391
|
NOTE: There are `public`, `private` and `protected` methods in `Ruby`
|
310
392
|
(for more details you can check on [Programming Ruby](http://www.ruby-doc.org/docs/ProgrammingRuby/)).
|
@@ -314,44 +396,77 @@ If you refresh <http://localhost:3000/posts/new> now, you'll get a new error:
|
|
314
396
|
|
315
397
|
![Unknown action new for PostsController!](images/getting_started/unknown_action_new_for_posts.png)
|
316
398
|
|
317
|
-
This error indicates that Rails cannot find the `new` action inside the `PostsController`
|
399
|
+
This error indicates that Rails cannot find the `new` action inside the `PostsController`
|
400
|
+
that you just generated. This is because when controllers are generated in Rails
|
401
|
+
they are empty by default, unless you tell it your wanted actions during the
|
402
|
+
generation process.
|
318
403
|
|
319
|
-
To manually define an action inside a controller, all you need to do is to
|
404
|
+
To manually define an action inside a controller, all you need to do is to
|
405
|
+
define a new method inside the controller. Open `app/controllers/posts_controller.rb`
|
406
|
+
and inside the `PostsController` class, define a `new` method like this:
|
320
407
|
|
321
408
|
```ruby
|
322
409
|
def new
|
323
410
|
end
|
324
411
|
```
|
325
412
|
|
326
|
-
With the `new` method defined in `PostsController`, if you refresh <http://localhost:3000/posts/new>
|
413
|
+
With the `new` method defined in `PostsController`, if you refresh <http://localhost:3000/posts/new>
|
414
|
+
you'll see another error:
|
327
415
|
|
328
416
|
![Template is missing for posts/new](images/getting_started/template_is_missing_posts_new.png)
|
329
417
|
|
330
|
-
You're getting this error now because Rails expects plain actions like this one
|
418
|
+
You're getting this error now because Rails expects plain actions like this one
|
419
|
+
to have views associated with them to display their information. With no view
|
420
|
+
available, Rails errors out.
|
331
421
|
|
332
|
-
In the above image, the bottom line has been truncated. Let's see what the full
|
422
|
+
In the above image, the bottom line has been truncated. Let's see what the full
|
423
|
+
thing looks like:
|
333
424
|
|
334
425
|
<blockquote>
|
335
426
|
Missing template posts/new, application/new with {locale:[:en], formats:[:html], handlers:[:erb, :builder, :coffee]}. Searched in: * "/path/to/blog/app/views"
|
336
427
|
</blockquote>
|
337
428
|
|
338
|
-
That's quite a lot of text! Let's quickly go through and understand what each
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
The
|
347
|
-
|
348
|
-
|
429
|
+
That's quite a lot of text! Let's quickly go through and understand what each
|
430
|
+
part of it does.
|
431
|
+
|
432
|
+
The first part identifies what template is missing. In this case, it's the
|
433
|
+
`posts/new` template. Rails will first look for this template. If not found,
|
434
|
+
then it will attempt to load a template called `application/new`. It looks for
|
435
|
+
one here because the `PostsController` inherits from `ApplicationController`.
|
436
|
+
|
437
|
+
The next part of the message contains a hash. The `:locale` key in this hash
|
438
|
+
simply indicates what spoken language template should be retrieved. By default,
|
439
|
+
this is the English - or "en" - template. The next key, `:formats` specifies the
|
440
|
+
format of template to be served in response. The default format is `:html`, and
|
441
|
+
so Rails is looking for an HTML template. The final key, `:handlers`, is telling
|
442
|
+
us what _template handlers_ could be used to render our template. `:erb` is most
|
443
|
+
commonly used for HTML templates, `:builder` is used for XML templates, and
|
444
|
+
`:coffee` uses CoffeeScript to build JavaScript templates.
|
445
|
+
|
446
|
+
The final part of this message tells us where Rails has looked for the templates.
|
447
|
+
Templates within a basic Rails application like this are kept in a single
|
448
|
+
location, but in more complex applications it could be many different paths.
|
449
|
+
|
450
|
+
The simplest template that would work in this case would be one located at
|
451
|
+
`app/views/posts/new.html.erb`. The extension of this file name is key: the
|
452
|
+
first extension is the _format_ of the template, and the second extension is the
|
453
|
+
_handler_ that will be used. Rails is attempting to find a template called
|
454
|
+
`posts/new` within `app/views` for the application. The format for this template
|
455
|
+
can only be `html` and the handler must be one of `erb`, `builder` or `coffee`.
|
456
|
+
Because you want to create a new HTML form, you will be using the `ERB`
|
457
|
+
language. Therefore the file should be called `posts/new.html.erb` and needs to
|
458
|
+
be located inside the `app/views` directory of the application.
|
459
|
+
|
460
|
+
Go ahead now and create a new file at `app/views/posts/new.html.erb` and write
|
461
|
+
this content in it:
|
349
462
|
|
350
463
|
```html
|
351
464
|
<h1>New Post</h1>
|
352
465
|
```
|
353
466
|
|
354
|
-
When you refresh <http://localhost:3000/posts/new> you'll now see that the page
|
467
|
+
When you refresh <http://localhost:3000/posts/new> you'll now see that the page
|
468
|
+
has a title. The route, controller, action and view are now working
|
469
|
+
harmoniously! It's time to create the form for a new post.
|
355
470
|
|
356
471
|
### The first form
|
357
472
|
|
@@ -377,14 +492,21 @@ method called `form_for`. To use this method, add this code into `app/views/post
|
|
377
492
|
<% end %>
|
378
493
|
```
|
379
494
|
|
380
|
-
If you refresh the page now, you'll see the exact same form as in the example.
|
495
|
+
If you refresh the page now, you'll see the exact same form as in the example.
|
496
|
+
Building forms in Rails is really just that easy!
|
381
497
|
|
382
498
|
When you call `form_for`, you pass it an identifying object for this
|
383
499
|
form. In this case, it's the symbol `:post`. This tells the `form_for`
|
384
500
|
helper what this form is for. Inside the block for this method, the
|
385
|
-
`FormBuilder` object
|
501
|
+
`FormBuilder` object - represented by `f` - is used to build two labels and two
|
502
|
+
text fields, one each for the title and text of a post. Finally, a call to
|
503
|
+
`submit` on the `f` object will create a submit button for the form.
|
386
504
|
|
387
|
-
There's one problem with this form though. If you inspect the HTML that is
|
505
|
+
There's one problem with this form though. If you inspect the HTML that is
|
506
|
+
generated, by viewing the source of the page, you will see that the `action`
|
507
|
+
attribute for the form is pointing at `/posts/new`. This is a problem because
|
508
|
+
this route goes to the very page that you're on right at the moment, and that
|
509
|
+
route should only be used to display the form for a new post.
|
388
510
|
|
389
511
|
The form needs to use a different URL in order to go somewhere else.
|
390
512
|
This can be done quite simply with the `:url` option of `form_for`.
|
@@ -397,19 +519,45 @@ Edit the `form_for` line inside `app/views/posts/new.html.erb` to look like this
|
|
397
519
|
<%= form_for :post, url: posts_path do |f| %>
|
398
520
|
```
|
399
521
|
|
400
|
-
In this example, the `posts_path` helper is passed to the `:url` option.
|
522
|
+
In this example, the `posts_path` helper is passed to the `:url` option.
|
523
|
+
To see what Rails will do with this, we look back at the output of
|
524
|
+
`rake routes`:
|
525
|
+
|
526
|
+
```bash
|
527
|
+
$ rake routes
|
528
|
+
Prefix Verb URI Pattern Controller#Action
|
529
|
+
posts GET /posts(.:format) posts#index
|
530
|
+
POST /posts(.:format) posts#create
|
531
|
+
new_post GET /posts/new(.:format) posts#new
|
532
|
+
edit_post GET /posts/:id/edit(.:format) posts#edit
|
533
|
+
post GET /posts/:id(.:format) posts#show
|
534
|
+
PATCH /posts/:id(.:format) posts#update
|
535
|
+
PUT /posts/:id(.:format) posts#update
|
536
|
+
DELETE /posts/:id(.:format) posts#destroy
|
537
|
+
root / welcome#index
|
538
|
+
```
|
401
539
|
|
402
|
-
|
540
|
+
The `posts_path` helper tells Rails to point the form
|
541
|
+
to the URI Pattern associated with the `posts` prefix; and
|
542
|
+
the form will (by default) send a `POST` request
|
543
|
+
to that route. This is associated with the
|
544
|
+
`create` action of the current controller, the `PostsController`.
|
403
545
|
|
404
|
-
With the form and its associated route defined, you will be able to fill in the
|
546
|
+
With the form and its associated route defined, you will be able to fill in the
|
547
|
+
form and then click the submit button to begin the process of creating a new
|
548
|
+
post, so go ahead and do that. When you submit the form, you should see a
|
549
|
+
familiar error:
|
405
550
|
|
406
551
|
![Unknown action create for PostsController](images/getting_started/unknown_action_create_for_posts.png)
|
407
552
|
|
408
|
-
You now need to create the `create` action within the `PostsController` for this
|
553
|
+
You now need to create the `create` action within the `PostsController` for this
|
554
|
+
to work.
|
409
555
|
|
410
556
|
### Creating posts
|
411
557
|
|
412
|
-
To make the "Unknown action" go away, you can define a `create` action within
|
558
|
+
To make the "Unknown action" go away, you can define a `create` action within
|
559
|
+
the `PostsController` class in `app/controllers/posts_controller.rb`, underneath
|
560
|
+
the `new` action:
|
413
561
|
|
414
562
|
```ruby
|
415
563
|
class PostsController < ApplicationController
|
@@ -421,9 +569,14 @@ class PostsController < ApplicationController
|
|
421
569
|
end
|
422
570
|
```
|
423
571
|
|
424
|
-
If you re-submit the form now, you'll see another familiar error: a template is
|
572
|
+
If you re-submit the form now, you'll see another familiar error: a template is
|
573
|
+
missing. That's ok, we can ignore that for now. What the `create` action should
|
574
|
+
be doing is saving our new post to a database.
|
425
575
|
|
426
|
-
When a form is submitted, the fields of the form are sent to Rails as
|
576
|
+
When a form is submitted, the fields of the form are sent to Rails as
|
577
|
+
_parameters_. These parameters can then be referenced inside the controller
|
578
|
+
actions, typically to perform a particular task. To see what these parameters
|
579
|
+
look like, change the `create` action to this:
|
427
580
|
|
428
581
|
```ruby
|
429
582
|
def create
|
@@ -431,15 +584,23 @@ def create
|
|
431
584
|
end
|
432
585
|
```
|
433
586
|
|
434
|
-
The `render` method here is taking a very simple hash with a key of `text` and
|
587
|
+
The `render` method here is taking a very simple hash with a key of `text` and
|
588
|
+
value of `params[:post].inspect`. The `params` method is the object which
|
589
|
+
represents the parameters (or fields) coming in from the form. The `params`
|
590
|
+
method returns an `ActiveSupport::HashWithIndifferentAccess` object, which
|
591
|
+
allows you to access the keys of the hash using either strings or symbols. In
|
592
|
+
this situation, the only parameters that matter are the ones from the form.
|
435
593
|
|
436
|
-
If you re-submit the form one more time you'll now no longer get the missing
|
594
|
+
If you re-submit the form one more time you'll now no longer get the missing
|
595
|
+
template error. Instead, you'll see something that looks like the following:
|
437
596
|
|
438
597
|
```ruby
|
439
598
|
{"title"=>"First post!", "text"=>"This is my first post."}
|
440
599
|
```
|
441
600
|
|
442
|
-
This action is now displaying the parameters for the post that are coming in
|
601
|
+
This action is now displaying the parameters for the post that are coming in
|
602
|
+
from the form. However, this isn't really all that helpful. Yes, you can see the
|
603
|
+
parameters but nothing in particular is being done with them.
|
443
604
|
|
444
605
|
### Creating the Post model
|
445
606
|
|
@@ -528,13 +689,14 @@ invoking the command: `rake db:migrate RAILS_ENV=production`.
|
|
528
689
|
|
529
690
|
### Saving data in the controller
|
530
691
|
|
531
|
-
Back in `
|
692
|
+
Back in `PostsController`, we need to change the `create` action
|
532
693
|
to use the new `Post` model to save the data in the database. Open `app/controllers/posts_controller.rb`
|
533
694
|
and change the `create` action to look like this:
|
534
695
|
|
535
696
|
```ruby
|
536
697
|
def create
|
537
698
|
@post = Post.new(params[:post])
|
699
|
+
|
538
700
|
@post.save
|
539
701
|
redirect_to @post
|
540
702
|
end
|
@@ -542,11 +704,10 @@ end
|
|
542
704
|
|
543
705
|
Here's what's going on: every Rails model can be initialized with its
|
544
706
|
respective attributes, which are automatically mapped to the respective
|
545
|
-
database columns. In the first line we do just that
|
546
|
-
`params[:post]` contains the attributes we're interested in).
|
547
|
-
`@post.save` is responsible for saving the model in the database.
|
548
|
-
Finally, we redirect the user to the `show` action,
|
549
|
-
which we'll define later.
|
707
|
+
database columns. In the first line we do just that
|
708
|
+
(remember that `params[:post]` contains the attributes we're interested in).
|
709
|
+
Then, `@post.save` is responsible for saving the model in the database.
|
710
|
+
Finally, we redirect the user to the `show` action, which we'll define later.
|
550
711
|
|
551
712
|
TIP: As we'll see later, `@post.save` returns a boolean indicating
|
552
713
|
whether the model was saved or not.
|
@@ -581,8 +742,9 @@ private
|
|
581
742
|
See the `permit`? It allows us to accept both `title` and `text` in this
|
582
743
|
action.
|
583
744
|
|
584
|
-
TIP: Note that `def post_params` is private. This new approach prevents an
|
585
|
-
setting the model's attributes by manipulating the hash passed to
|
745
|
+
TIP: Note that `def post_params` is private. This new approach prevents an
|
746
|
+
attacker from setting the model's attributes by manipulating the hash passed to
|
747
|
+
the model.
|
586
748
|
For more information, refer to
|
587
749
|
[this blog post about Strong Parameters](http://weblog.rubyonrails.org/2012/3/21/strong-parameters/).
|
588
750
|
|
@@ -595,7 +757,7 @@ the `show` action. That's not very useful though, so let's add the
|
|
595
757
|
As we have seen in the output of `rake routes`, the route for `show` action is
|
596
758
|
as follows:
|
597
759
|
|
598
|
-
```
|
760
|
+
```ruby
|
599
761
|
post GET /posts/:id(.:format) posts#show
|
600
762
|
```
|
601
763
|
|
@@ -612,8 +774,9 @@ end
|
|
612
774
|
```
|
613
775
|
|
614
776
|
A couple of things to note. We use `Post.find` to find the post we're
|
615
|
-
interested in
|
616
|
-
|
777
|
+
interested in, passing in `params[:id]` to get the `:id` parameter from the
|
778
|
+
request. We also use an instance variable (prefixed by `@`) to hold a
|
779
|
+
reference to the post object. We do this because Rails will pass all instance
|
617
780
|
variables to the view.
|
618
781
|
|
619
782
|
Now, create a new file `app/views/posts/show.html.erb` with the following
|
@@ -639,13 +802,13 @@ Visit <http://localhost:3000/posts/new> and give it a try!
|
|
639
802
|
### Listing all posts
|
640
803
|
|
641
804
|
We still need a way to list all our posts, so let's do that.
|
642
|
-
|
805
|
+
The route for this as per output of `rake routes` is:
|
643
806
|
|
644
807
|
```ruby
|
645
808
|
posts GET /posts(.:format) posts#index
|
646
809
|
```
|
647
810
|
|
648
|
-
|
811
|
+
Add the corresponding `index` action for that route inside the `PostsController` in the `app/controllers/posts_controller.rb` file:
|
649
812
|
|
650
813
|
```ruby
|
651
814
|
def index
|
@@ -673,7 +836,8 @@ And then finally a view for this action, located at `app/views/posts/index.html.
|
|
673
836
|
</table>
|
674
837
|
```
|
675
838
|
|
676
|
-
Now if you go to `http://localhost:3000/posts` you will see a list of all the
|
839
|
+
Now if you go to `http://localhost:3000/posts` you will see a list of all the
|
840
|
+
posts that you have created.
|
677
841
|
|
678
842
|
### Adding links
|
679
843
|
|
@@ -684,20 +848,24 @@ Open `app/views/welcome/index.html.erb` and modify it as follows:
|
|
684
848
|
|
685
849
|
```html+erb
|
686
850
|
<h1>Hello, Rails!</h1>
|
687
|
-
<%= link_to
|
851
|
+
<%= link_to 'My Blog', controller: 'posts' %>
|
688
852
|
```
|
689
853
|
|
690
854
|
The `link_to` method is one of Rails' built-in view helpers. It creates a
|
691
855
|
hyperlink based on text to display and where to go - in this case, to the path
|
692
856
|
for posts.
|
693
857
|
|
694
|
-
Let's add links to the other views as well, starting with adding this "New Post"
|
858
|
+
Let's add links to the other views as well, starting with adding this "New Post"
|
859
|
+
link to `app/views/posts/index.html.erb`, placing it above the `<table>` tag:
|
695
860
|
|
696
861
|
```erb
|
697
862
|
<%= link_to 'New post', new_post_path %>
|
698
863
|
```
|
699
864
|
|
700
|
-
This link will allow you to bring up the form that lets you create a new post.
|
865
|
+
This link will allow you to bring up the form that lets you create a new post.
|
866
|
+
You should also add a link to this template - `app/views/posts/new.html.erb` -
|
867
|
+
to go back to the `index` action. Do this by adding this underneath the form in
|
868
|
+
this template:
|
701
869
|
|
702
870
|
```erb
|
703
871
|
<%= form_for :post do |f| %>
|
@@ -707,7 +875,9 @@ This link will allow you to bring up the form that lets you create a new post. Y
|
|
707
875
|
<%= link_to 'Back', posts_path %>
|
708
876
|
```
|
709
877
|
|
710
|
-
Finally, add another link to the `app/views/posts/show.html.erb` template to go
|
878
|
+
Finally, add another link to the `app/views/posts/show.html.erb` template to go
|
879
|
+
back to the `index` action as well, so that people who are viewing a single post
|
880
|
+
can go back and view the whole list again:
|
711
881
|
|
712
882
|
```html+erb
|
713
883
|
<p>
|
@@ -731,7 +901,7 @@ TIP: In development mode (which is what you're working in by default), Rails
|
|
731
901
|
reloads your application with every browser request, so there's no need to stop
|
732
902
|
and restart the web server when a change is made.
|
733
903
|
|
734
|
-
###
|
904
|
+
### Adding Some Validation
|
735
905
|
|
736
906
|
The model file, `app/models/post.rb` is about as simple as it can get:
|
737
907
|
|
@@ -746,8 +916,6 @@ your Rails models for free, including basic database CRUD (Create, Read, Update,
|
|
746
916
|
Destroy) operations, data validation, as well as sophisticated search support
|
747
917
|
and the ability to relate multiple models to one another.
|
748
918
|
|
749
|
-
### Adding Some Validation
|
750
|
-
|
751
919
|
Rails includes methods to help you validate the data that you send to models.
|
752
920
|
Open the `app/models/post.rb` file and edit it:
|
753
921
|
|
@@ -759,7 +927,7 @@ end
|
|
759
927
|
```
|
760
928
|
|
761
929
|
These changes will ensure that all posts have a title that is at least five
|
762
|
-
characters long.
|
930
|
+
characters long. Rails can validate a variety of conditions in a model,
|
763
931
|
including the presence or uniqueness of columns, their format, and the
|
764
932
|
existence of associated objects. Validations are covered in detail in [Active
|
765
933
|
Record Validations](active_record_validations.html)
|
@@ -777,7 +945,7 @@ def new
|
|
777
945
|
end
|
778
946
|
|
779
947
|
def create
|
780
|
-
@post = Post.new(
|
948
|
+
@post = Post.new(post_params)
|
781
949
|
|
782
950
|
if @post.save
|
783
951
|
redirect_to @post
|
@@ -785,13 +953,21 @@ def create
|
|
785
953
|
render 'new'
|
786
954
|
end
|
787
955
|
end
|
956
|
+
|
957
|
+
private
|
958
|
+
def post_params
|
959
|
+
params.require(:post).permit(:title, :text)
|
960
|
+
end
|
788
961
|
```
|
789
962
|
|
790
963
|
The `new` action is now creating a new instance variable called `@post`, and
|
791
964
|
you'll see why that is in just a few moments.
|
792
965
|
|
793
|
-
Notice that inside the `create` action we use `render` instead of `redirect_to`
|
794
|
-
returns `false`. The `render` method is used so that the `@post`
|
966
|
+
Notice that inside the `create` action we use `render` instead of `redirect_to`
|
967
|
+
when `save` returns `false`. The `render` method is used so that the `@post`
|
968
|
+
object is passed back to the `new` template when it is rendered. This rendering
|
969
|
+
is done within the same request as the form submission, whereas the `redirect_to`
|
970
|
+
will tell the browser to issue another request.
|
795
971
|
|
796
972
|
If you reload
|
797
973
|
<http://localhost:3000/posts/new> and
|
@@ -836,9 +1012,10 @@ A few things are going on. We check if there are any errors with
|
|
836
1012
|
errors with `@post.errors.full_messages`.
|
837
1013
|
|
838
1014
|
`pluralize` is a rails helper that takes a number and a string as its
|
839
|
-
arguments. If the number is greater than one, the string will be automatically
|
1015
|
+
arguments. If the number is greater than one, the string will be automatically
|
1016
|
+
pluralized.
|
840
1017
|
|
841
|
-
The reason why we added `@post = Post.new` in `
|
1018
|
+
The reason why we added `@post = Post.new` in the `PostsController` is that
|
842
1019
|
otherwise `@post` would be `nil` in our view, and calling
|
843
1020
|
`@post.errors.any?` would throw an error.
|
844
1021
|
|
@@ -853,9 +1030,10 @@ attempt to do just that on the new post form [(http://localhost:3000/posts/new)]
|
|
853
1030
|
|
854
1031
|
### Updating Posts
|
855
1032
|
|
856
|
-
We've covered the "CR" part of CRUD. Now let's focus on the "U" part, updating
|
1033
|
+
We've covered the "CR" part of CRUD. Now let's focus on the "U" part, updating
|
1034
|
+
posts.
|
857
1035
|
|
858
|
-
The first step we'll take is adding an `edit` action to `
|
1036
|
+
The first step we'll take is adding an `edit` action to the `PostsController`.
|
859
1037
|
|
860
1038
|
```ruby
|
861
1039
|
def edit
|
@@ -915,12 +1093,17 @@ Next we need to create the `update` action in `app/controllers/posts_controller.
|
|
915
1093
|
def update
|
916
1094
|
@post = Post.find(params[:id])
|
917
1095
|
|
918
|
-
if @post.update(
|
1096
|
+
if @post.update(post_params)
|
919
1097
|
redirect_to @post
|
920
1098
|
else
|
921
1099
|
render 'edit'
|
922
1100
|
end
|
923
1101
|
end
|
1102
|
+
|
1103
|
+
private
|
1104
|
+
def post_params
|
1105
|
+
params.require(:post).permit(:title, :text)
|
1106
|
+
end
|
924
1107
|
```
|
925
1108
|
|
926
1109
|
The new method, `update`, is used when you want to update a record
|
@@ -928,6 +1111,8 @@ that already exists, and it accepts a hash containing the attributes
|
|
928
1111
|
that you want to update. As before, if there was an error updating the
|
929
1112
|
post we want to show the form back to the user.
|
930
1113
|
|
1114
|
+
We reuse the `post_params` method that we defined earlier for the create action.
|
1115
|
+
|
931
1116
|
TIP: You don't need to pass all attributes to `update`. For
|
932
1117
|
example, if you'd call `@post.update(title: 'A new title')`
|
933
1118
|
Rails would only update the `title` attribute, leaving all other
|
@@ -942,15 +1127,14 @@ appear next to the "Show" link:
|
|
942
1127
|
<tr>
|
943
1128
|
<th>Title</th>
|
944
1129
|
<th>Text</th>
|
945
|
-
<th></th>
|
946
|
-
<th></th>
|
1130
|
+
<th colspan="2"></th>
|
947
1131
|
</tr>
|
948
1132
|
|
949
1133
|
<% @posts.each do |post| %>
|
950
1134
|
<tr>
|
951
1135
|
<td><%= post.title %></td>
|
952
1136
|
<td><%= post.text %></td>
|
953
|
-
<td><%= link_to 'Show', post %></td>
|
1137
|
+
<td><%= link_to 'Show', post_path(post) %></td>
|
954
1138
|
<td><%= link_to 'Edit', edit_post_path(post) %></td>
|
955
1139
|
</tr>
|
956
1140
|
<% end %>
|
@@ -1015,10 +1199,15 @@ content:
|
|
1015
1199
|
```
|
1016
1200
|
|
1017
1201
|
Everything except for the `form_for` declaration remained the same.
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1202
|
+
The reason we can use this shorter, simpler `form_for` declaration
|
1203
|
+
to stand in for either of the other forms is that `@post` is a *resource*
|
1204
|
+
corresponding to a full set of RESTful routes, and Rails is able to infer
|
1205
|
+
which URI and method to use.
|
1206
|
+
For more information about this use of `form_for`, see
|
1207
|
+
[Resource-oriented style](//api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for-label-Resource-oriented+style).
|
1208
|
+
|
1209
|
+
Now, let's update the `app/views/posts/new.html.erb` view to use this new
|
1210
|
+
partial, rewriting it completely:
|
1022
1211
|
|
1023
1212
|
```html+erb
|
1024
1213
|
<h1>New post</h1>
|
@@ -1042,7 +1231,7 @@ Then do the same for the `app/views/posts/edit.html.erb` view:
|
|
1042
1231
|
|
1043
1232
|
We're now ready to cover the "D" part of CRUD, deleting posts from the
|
1044
1233
|
database. Following the REST convention, the route for
|
1045
|
-
deleting posts
|
1234
|
+
deleting posts as per output of `rake routes` is:
|
1046
1235
|
|
1047
1236
|
```ruby
|
1048
1237
|
DELETE /posts/:id(.:format) posts#destroy
|
@@ -1057,8 +1246,8 @@ people to craft malicious URLs like this:
|
|
1057
1246
|
```
|
1058
1247
|
|
1059
1248
|
We use the `delete` method for destroying resources, and this route is mapped to
|
1060
|
-
the `destroy` action inside `app/controllers/posts_controller.rb`, which doesn't
|
1061
|
-
provided below:
|
1249
|
+
the `destroy` action inside `app/controllers/posts_controller.rb`, which doesn't
|
1250
|
+
exist yet, but is provided below:
|
1062
1251
|
|
1063
1252
|
```ruby
|
1064
1253
|
def destroy
|
@@ -1073,7 +1262,7 @@ You can call `destroy` on Active Record objects when you want to delete
|
|
1073
1262
|
them from the database. Note that we don't need to add a view for this
|
1074
1263
|
action since we're redirecting to the `index` action.
|
1075
1264
|
|
1076
|
-
Finally, add a '
|
1265
|
+
Finally, add a 'Destroy' link to your `index` action template
|
1077
1266
|
(`app/views/posts/index.html.erb`) to wrap everything
|
1078
1267
|
together.
|
1079
1268
|
|
@@ -1084,9 +1273,7 @@ together.
|
|
1084
1273
|
<tr>
|
1085
1274
|
<th>Title</th>
|
1086
1275
|
<th>Text</th>
|
1087
|
-
<th></th>
|
1088
|
-
<th></th>
|
1089
|
-
<th></th>
|
1276
|
+
<th colspan="3"></th>
|
1090
1277
|
</tr>
|
1091
1278
|
|
1092
1279
|
<% @posts.each do |post| %>
|
@@ -1102,13 +1289,14 @@ together.
|
|
1102
1289
|
</table>
|
1103
1290
|
```
|
1104
1291
|
|
1105
|
-
Here we're using `link_to` in a different way. We pass the named route as the
|
1106
|
-
and then the
|
1107
|
-
options are used as HTML5 attributes so that when the link is
|
1108
|
-
Rails will first show a confirm dialog to the user, and then submit the
|
1109
|
-
This is done via the JavaScript file `jquery_ujs`
|
1110
|
-
into your application's layout
|
1111
|
-
|
1292
|
+
Here we're using `link_to` in a different way. We pass the named route as the
|
1293
|
+
second argument, and then the options as another argument. The `:method` and
|
1294
|
+
`:'data-confirm'` options are used as HTML5 attributes so that when the link is
|
1295
|
+
clicked, Rails will first show a confirm dialog to the user, and then submit the
|
1296
|
+
link with method `delete`. This is done via the JavaScript file `jquery_ujs`
|
1297
|
+
which is automatically included into your application's layout
|
1298
|
+
(`app/views/layouts/application.html.erb`) when you generated the application.
|
1299
|
+
Without this file, the confirmation dialog box wouldn't appear.
|
1112
1300
|
|
1113
1301
|
![Confirm Dialog](images/getting_started/confirm_dialog.png)
|
1114
1302
|
|
@@ -1123,8 +1311,8 @@ For more information about routing, see
|
|
1123
1311
|
Adding a Second Model
|
1124
1312
|
---------------------
|
1125
1313
|
|
1126
|
-
It's time to add a second model to the application. The second model will handle
|
1127
|
-
posts.
|
1314
|
+
It's time to add a second model to the application. The second model will handle
|
1315
|
+
comments on posts.
|
1128
1316
|
|
1129
1317
|
### Generating a Model
|
1130
1318
|
|
@@ -1153,7 +1341,7 @@ class Comment < ActiveRecord::Base
|
|
1153
1341
|
end
|
1154
1342
|
```
|
1155
1343
|
|
1156
|
-
This is very similar to the `
|
1344
|
+
This is very similar to the `Post` model that you saw earlier. The difference
|
1157
1345
|
is the line `belongs_to :post`, which sets up an Active Record _association_.
|
1158
1346
|
You'll learn a little about associations in the next section of this guide.
|
1159
1347
|
|
@@ -1166,19 +1354,17 @@ class CreateComments < ActiveRecord::Migration
|
|
1166
1354
|
create_table :comments do |t|
|
1167
1355
|
t.string :commenter
|
1168
1356
|
t.text :body
|
1169
|
-
t.references :post
|
1357
|
+
t.references :post, index: true
|
1170
1358
|
|
1171
1359
|
t.timestamps
|
1172
1360
|
end
|
1173
|
-
|
1174
|
-
add_index :comments, :post_id
|
1175
1361
|
end
|
1176
1362
|
end
|
1177
1363
|
```
|
1178
1364
|
|
1179
1365
|
The `t.references` line sets up a foreign key column for the association between
|
1180
|
-
the two models.
|
1181
|
-
|
1366
|
+
the two models. An index for this association is also created on this column.
|
1367
|
+
Go ahead and run the migration:
|
1182
1368
|
|
1183
1369
|
```bash
|
1184
1370
|
$ rake db:migrate
|
@@ -1190,10 +1376,8 @@ run against the current database, so in this case you will just see:
|
|
1190
1376
|
```bash
|
1191
1377
|
== CreateComments: migrating =================================================
|
1192
1378
|
-- create_table(:comments)
|
1193
|
-
-> 0.
|
1194
|
-
|
1195
|
-
-> 0.0003s
|
1196
|
-
== CreateComments: migrated (0.0012s) ========================================
|
1379
|
+
-> 0.0115s
|
1380
|
+
== CreateComments: migrated (0.0119s) ========================================
|
1197
1381
|
```
|
1198
1382
|
|
1199
1383
|
### Associating Models
|
@@ -1206,8 +1390,8 @@ this way:
|
|
1206
1390
|
* One post can have many comments.
|
1207
1391
|
|
1208
1392
|
In fact, this is very close to the syntax that Rails uses to declare this
|
1209
|
-
association. You've already seen the line of code inside the `Comment` model
|
1210
|
-
makes each comment belong to a Post:
|
1393
|
+
association. You've already seen the line of code inside the `Comment` model
|
1394
|
+
(app/models/comment.rb) that makes each comment belong to a Post:
|
1211
1395
|
|
1212
1396
|
```ruby
|
1213
1397
|
class Comment < ActiveRecord::Base
|
@@ -1295,11 +1479,11 @@ So first, we'll wire up the Post show template
|
|
1295
1479
|
<h2>Add a comment:</h2>
|
1296
1480
|
<%= form_for([@post, @post.comments.build]) do |f| %>
|
1297
1481
|
<p>
|
1298
|
-
<%= f.label :commenter %><br
|
1482
|
+
<%= f.label :commenter %><br>
|
1299
1483
|
<%= f.text_field :commenter %>
|
1300
1484
|
</p>
|
1301
1485
|
<p>
|
1302
|
-
<%= f.label :body %><br
|
1486
|
+
<%= f.label :body %><br>
|
1303
1487
|
<%= f.text_area :body %>
|
1304
1488
|
</p>
|
1305
1489
|
<p>
|
@@ -1321,9 +1505,14 @@ Let's wire up the `create` in `app/controllers/comments_controller.rb`:
|
|
1321
1505
|
class CommentsController < ApplicationController
|
1322
1506
|
def create
|
1323
1507
|
@post = Post.find(params[:post_id])
|
1324
|
-
@comment = @post.comments.create(
|
1508
|
+
@comment = @post.comments.create(comment_params)
|
1325
1509
|
redirect_to post_path(@post)
|
1326
1510
|
end
|
1511
|
+
|
1512
|
+
private
|
1513
|
+
def comment_params
|
1514
|
+
params.require(:comment).permit(:commenter, :body)
|
1515
|
+
end
|
1327
1516
|
end
|
1328
1517
|
```
|
1329
1518
|
|
@@ -1370,11 +1559,11 @@ template. This is where we want the comment to show, so let's add that to the
|
|
1370
1559
|
<h2>Add a comment:</h2>
|
1371
1560
|
<%= form_for([@post, @post.comments.build]) do |f| %>
|
1372
1561
|
<p>
|
1373
|
-
<%= f.label :commenter %><br
|
1562
|
+
<%= f.label :commenter %><br>
|
1374
1563
|
<%= f.text_field :commenter %>
|
1375
1564
|
</p>
|
1376
1565
|
<p>
|
1377
|
-
<%= f.label :body %><br
|
1566
|
+
<%= f.label :body %><br>
|
1378
1567
|
<%= f.text_area :body %>
|
1379
1568
|
</p>
|
1380
1569
|
<p>
|
@@ -1436,11 +1625,11 @@ following:
|
|
1436
1625
|
<h2>Add a comment:</h2>
|
1437
1626
|
<%= form_for([@post, @post.comments.build]) do |f| %>
|
1438
1627
|
<p>
|
1439
|
-
<%= f.label :commenter %><br
|
1628
|
+
<%= f.label :commenter %><br>
|
1440
1629
|
<%= f.text_field :commenter %>
|
1441
1630
|
</p>
|
1442
1631
|
<p>
|
1443
|
-
<%= f.label :body %><br
|
1632
|
+
<%= f.label :body %><br>
|
1444
1633
|
<%= f.text_area :body %>
|
1445
1634
|
</p>
|
1446
1635
|
<p>
|
@@ -1466,11 +1655,11 @@ create a file `app/views/comments/_form.html.erb` containing:
|
|
1466
1655
|
```html+erb
|
1467
1656
|
<%= form_for([@post, @post.comments.build]) do |f| %>
|
1468
1657
|
<p>
|
1469
|
-
<%= f.label :commenter %><br
|
1658
|
+
<%= f.label :commenter %><br>
|
1470
1659
|
<%= f.text_field :commenter %>
|
1471
1660
|
</p>
|
1472
1661
|
<p>
|
1473
|
-
<%= f.label :body %><br
|
1662
|
+
<%= f.label :body %><br>
|
1474
1663
|
<%= f.text_area :body %>
|
1475
1664
|
</p>
|
1476
1665
|
<p>
|
@@ -1545,10 +1734,9 @@ controller (`app/controllers/comments_controller.rb`):
|
|
1545
1734
|
|
1546
1735
|
```ruby
|
1547
1736
|
class CommentsController < ApplicationController
|
1548
|
-
|
1549
1737
|
def create
|
1550
1738
|
@post = Post.find(params[:post_id])
|
1551
|
-
@comment = @post.comments.create(
|
1739
|
+
@comment = @post.comments.create(comment_params)
|
1552
1740
|
redirect_to post_path(@post)
|
1553
1741
|
end
|
1554
1742
|
|
@@ -1559,6 +1747,10 @@ class CommentsController < ApplicationController
|
|
1559
1747
|
redirect_to post_path(@post)
|
1560
1748
|
end
|
1561
1749
|
|
1750
|
+
private
|
1751
|
+
def comment_params
|
1752
|
+
params.require(:comment).permit(:commenter, :body)
|
1753
|
+
end
|
1562
1754
|
end
|
1563
1755
|
```
|
1564
1756
|
|
@@ -1586,6 +1778,8 @@ end
|
|
1586
1778
|
Security
|
1587
1779
|
--------
|
1588
1780
|
|
1781
|
+
### Basic Authentication
|
1782
|
+
|
1589
1783
|
If you were to publish your blog online, anybody would be able to add, edit and
|
1590
1784
|
delete posts or delete comments.
|
1591
1785
|
|
@@ -1625,6 +1819,7 @@ class CommentsController < ApplicationController
|
|
1625
1819
|
@post = Post.find(params[:post_id])
|
1626
1820
|
...
|
1627
1821
|
end
|
1822
|
+
|
1628
1823
|
# snipped for brevity
|
1629
1824
|
```
|
1630
1825
|
|
@@ -1633,6 +1828,19 @@ Authentication challenge
|
|
1633
1828
|
|
1634
1829
|
![Basic HTTP Authentication Challenge](images/getting_started/challenge.png)
|
1635
1830
|
|
1831
|
+
Other authentication methods are available for Rails applications. Two popular
|
1832
|
+
authentication add-ons for Rails are the [Devise](https://github.com/plataformatec/devise)
|
1833
|
+
rails engine and the [Authlogic](https://github.com/binarylogic/authlogic) gem,
|
1834
|
+
along with a number of others.
|
1835
|
+
|
1836
|
+
|
1837
|
+
### Other Security Considerations
|
1838
|
+
|
1839
|
+
Security, especially in web applications, is a broad and detailed area. Security
|
1840
|
+
in your Rails application is covered in more depth in
|
1841
|
+
The [Ruby on Rails Security Guide](security.html)
|
1842
|
+
|
1843
|
+
|
1636
1844
|
What's Next?
|
1637
1845
|
------------
|
1638
1846
|
|
@@ -1646,12 +1854,19 @@ free to consult these support resources:
|
|
1646
1854
|
* The [Ruby on Rails mailing list](http://groups.google.com/group/rubyonrails-talk)
|
1647
1855
|
* The [#rubyonrails](irc://irc.freenode.net/#rubyonrails) channel on irc.freenode.net
|
1648
1856
|
|
1649
|
-
Rails also comes with built-in help that you can generate using the rake
|
1857
|
+
Rails also comes with built-in help that you can generate using the rake
|
1858
|
+
command-line utility:
|
1650
1859
|
|
1651
|
-
* Running `rake doc:guides` will put a full copy of the Rails Guides in the
|
1652
|
-
|
1860
|
+
* Running `rake doc:guides` will put a full copy of the Rails Guides in the
|
1861
|
+
`doc/guides` folder of your application. Open `doc/guides/index.html` in your
|
1862
|
+
web browser to explore the Guides.
|
1863
|
+
* Running `rake doc:rails` will put a full copy of the API documentation for
|
1864
|
+
Rails in the `doc/api` folder of your application. Open `doc/api/index.html`
|
1865
|
+
in your web browser to explore the API documentation.
|
1653
1866
|
|
1654
|
-
TIP: To be able to generate the Rails Guides locally with the `doc:guides` rake
|
1867
|
+
TIP: To be able to generate the Rails Guides locally with the `doc:guides` rake
|
1868
|
+
task you need to install the RedCloth gem. Add it to your `Gemfile` and run
|
1869
|
+
`bundle install` and you're ready to go.
|
1655
1870
|
|
1656
1871
|
Configuration Gotchas
|
1657
1872
|
---------------------
|
@@ -1677,7 +1892,7 @@ Two very common sources of data that are not UTF-8:
|
|
1677
1892
|
in the browser. This also applies to your i18n translation files.
|
1678
1893
|
Most editors that do not already default to UTF-8 (such as some versions of
|
1679
1894
|
Dreamweaver) offer a way to change the default to UTF-8. Do so.
|
1680
|
-
* Your database
|
1895
|
+
* Your database: Rails defaults to converting data from your database into UTF-8 at
|
1681
1896
|
the boundary. However, if your database is not using UTF-8 internally, it may not
|
1682
1897
|
be able to store all characters that your users enter. For instance, if your database
|
1683
1898
|
is using Latin-1 internally, and your user enters a Russian, Hebrew, or Japanese
|