rails 4.0.0 → 4.2.11.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +30 -23
- data/guides/CHANGELOG.md +108 -6
- data/guides/Rakefile +21 -6
- data/guides/assets/images/akshaysurve.jpg +0 -0
- 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 +36 -34
- data/guides/assets/stylesheets/main.css +6 -2
- data/guides/assets/stylesheets/print.css +1 -1
- data/guides/bug_report_templates/action_controller_gem.rb +47 -0
- data/guides/bug_report_templates/action_controller_master.rb +54 -0
- data/guides/bug_report_templates/active_record_gem.rb +5 -2
- data/guides/bug_report_templates/active_record_master.rb +3 -2
- data/guides/bug_report_templates/generic_gem.rb +15 -0
- data/guides/bug_report_templates/generic_master.rb +26 -0
- data/guides/rails_guides.rb +23 -4
- data/guides/rails_guides/generator.rb +1 -1
- data/guides/rails_guides/helpers.rb +4 -2
- data/guides/rails_guides/levenshtein.rb +27 -21
- data/guides/rails_guides/markdown.rb +11 -7
- data/guides/rails_guides/markdown/renderer.rb +1 -1
- data/guides/source/2_2_release_notes.md +3 -3
- data/guides/source/2_3_release_notes.md +12 -12
- data/guides/source/3_0_release_notes.md +10 -13
- data/guides/source/3_1_release_notes.md +7 -4
- data/guides/source/3_2_release_notes.md +17 -14
- data/guides/source/4_0_release_notes.md +110 -54
- data/guides/source/4_1_release_notes.md +730 -0
- data/guides/source/4_2_release_notes.md +877 -0
- data/guides/source/_license.html.erb +1 -1
- data/guides/source/_welcome.html.erb +6 -2
- data/guides/source/action_controller_overview.md +223 -57
- data/guides/source/action_mailer_basics.md +129 -76
- data/guides/source/action_view_overview.md +247 -246
- data/guides/source/active_job_basics.md +339 -0
- data/guides/source/active_model_basics.md +374 -20
- data/guides/source/active_record_basics.md +46 -45
- data/guides/source/active_record_callbacks.md +83 -28
- data/guides/source/{migrations.md → active_record_migrations.md} +191 -275
- data/guides/source/active_record_postgresql.md +433 -0
- data/guides/source/active_record_querying.md +382 -300
- data/guides/source/active_record_validations.md +64 -55
- data/guides/source/active_support_core_extensions.md +229 -187
- data/guides/source/active_support_instrumentation.md +23 -22
- data/guides/source/api_documentation_guidelines.md +167 -15
- data/guides/source/asset_pipeline.md +768 -294
- data/guides/source/association_basics.md +188 -96
- data/guides/source/autoloading_and_reloading_constants.md +1311 -0
- data/guides/source/caching_with_rails.md +45 -11
- data/guides/source/command_line.md +96 -65
- data/guides/source/configuring.md +404 -70
- data/guides/source/contributing_to_ruby_on_rails.md +270 -130
- data/guides/source/credits.html.erb +7 -3
- data/guides/source/debugging_rails_applications.md +471 -284
- data/guides/source/development_dependencies_install.md +115 -21
- data/guides/source/documents.yaml +31 -9
- data/guides/source/engines.md +737 -291
- data/guides/source/form_helpers.md +137 -89
- data/guides/source/generators.md +60 -28
- data/guides/source/getting_started.md +1007 -596
- data/guides/source/i18n.md +178 -96
- data/guides/source/index.html.erb +2 -1
- data/guides/source/initialization.md +248 -104
- data/guides/source/kindle/toc.html.erb +1 -1
- data/guides/source/layout.html.erb +14 -22
- data/guides/source/layouts_and_rendering.md +78 -46
- data/guides/source/maintenance_policy.md +78 -0
- data/guides/source/nested_model_forms.md +10 -7
- data/guides/source/plugins.md +66 -57
- data/guides/source/rails_application_templates.md +49 -12
- data/guides/source/rails_on_rack.md +50 -60
- data/guides/source/routing.md +190 -139
- data/guides/source/ruby_on_rails_guides_guidelines.md +12 -13
- data/guides/source/security.md +134 -83
- data/guides/source/testing.md +322 -200
- data/guides/source/upgrading_ruby_on_rails.md +834 -37
- data/guides/source/working_with_javascript_in_rails.md +36 -26
- data/guides/w3c_validator.rb +2 -0
- metadata +93 -116
- 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/code/getting_started/Gemfile +0 -43
- data/guides/code/getting_started/Gemfile.lock +0 -150
- data/guides/code/getting_started/README.rdoc +0 -28
- data/guides/code/getting_started/Rakefile +0 -6
- data/guides/code/getting_started/app/assets/javascripts/application.js +0 -16
- data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
- data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
- data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
- data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -17
- data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -47
- data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
- data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
- data/guides/code/getting_started/app/models/comment.rb +0 -3
- data/guides/code/getting_started/app/models/post.rb +0 -7
- data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
- data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
- data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
- data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
- data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
- data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
- data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -3
- data/guides/code/getting_started/bin/bundle +0 -4
- data/guides/code/getting_started/bin/rails +0 -4
- data/guides/code/getting_started/bin/rake +0 -4
- data/guides/code/getting_started/config.ru +0 -4
- data/guides/code/getting_started/config/application.rb +0 -18
- data/guides/code/getting_started/config/boot.rb +0 -4
- data/guides/code/getting_started/config/database.yml +0 -25
- data/guides/code/getting_started/config/environment.rb +0 -5
- data/guides/code/getting_started/config/environments/development.rb +0 -30
- data/guides/code/getting_started/config/environments/production.rb +0 -80
- data/guides/code/getting_started/config/environments/test.rb +0 -36
- data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
- data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
- data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
- data/guides/code/getting_started/config/initializers/locale.rb +0 -9
- data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
- data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
- data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
- data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
- data/guides/code/getting_started/config/locales/en.yml +0 -23
- data/guides/code/getting_started/config/routes.rb +0 -7
- data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
- data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
- data/guides/code/getting_started/db/schema.rb +0 -33
- data/guides/code/getting_started/db/seeds.rb +0 -7
- data/guides/code/getting_started/public/404.html +0 -58
- data/guides/code/getting_started/public/422.html +0 -58
- data/guides/code/getting_started/public/500.html +0 -57
- data/guides/code/getting_started/public/favicon.ico +0 -0
- data/guides/code/getting_started/public/robots.txt +0 -5
- data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
- data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
- data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
- data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
- data/guides/code/getting_started/test/models/comment_test.rb +0 -7
- data/guides/code/getting_started/test/models/post_test.rb +0 -7
- data/guides/code/getting_started/test/test_helper.rb +0 -15
- data/guides/source/kindle/KINDLE.md +0 -26
@@ -17,7 +17,10 @@ After reading this guide, you will know:
|
|
17
17
|
Introduction
|
18
18
|
------------
|
19
19
|
|
20
|
-
Action Mailer allows you to send emails from your application using mailer classes
|
20
|
+
Action Mailer allows you to send emails from your application using mailer classes
|
21
|
+
and views. Mailers work very similarly to controllers. They inherit from
|
22
|
+
`ActionMailer::Base` and live in `app/mailers`, and they have associated views
|
23
|
+
that appear in `app/views`.
|
21
24
|
|
22
25
|
Sending Emails
|
23
26
|
--------------
|
@@ -30,12 +33,28 @@ views.
|
|
30
33
|
#### Create the Mailer
|
31
34
|
|
32
35
|
```bash
|
33
|
-
$ rails generate mailer UserMailer
|
36
|
+
$ bin/rails generate mailer UserMailer
|
34
37
|
create app/mailers/user_mailer.rb
|
38
|
+
create app/mailers/application_mailer.rb
|
35
39
|
invoke erb
|
36
40
|
create app/views/user_mailer
|
41
|
+
create app/views/layouts/mailer.text.erb
|
42
|
+
create app/views/layouts/mailer.html.erb
|
37
43
|
invoke test_unit
|
38
44
|
create test/mailers/user_mailer_test.rb
|
45
|
+
create test/mailers/previews/user_mailer_preview.rb
|
46
|
+
```
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
# app/mailers/application_mailer.rb
|
50
|
+
class ApplicationMailer < ActionMailer::Base
|
51
|
+
default from: "from@example.com"
|
52
|
+
layout 'mailer'
|
53
|
+
end
|
54
|
+
|
55
|
+
# app/mailers/user_mailer.rb
|
56
|
+
class UserMailer < ApplicationMailer
|
57
|
+
end
|
39
58
|
```
|
40
59
|
|
41
60
|
As you can see, you can generate mailers just like you use other generators with
|
@@ -60,8 +79,7 @@ delivered via email.
|
|
60
79
|
`app/mailers/user_mailer.rb` contains an empty mailer:
|
61
80
|
|
62
81
|
```ruby
|
63
|
-
class UserMailer <
|
64
|
-
default from: 'from@example.com'
|
82
|
+
class UserMailer < ApplicationMailer
|
65
83
|
end
|
66
84
|
```
|
67
85
|
|
@@ -69,7 +87,7 @@ Let's add a method called `welcome_email`, that will send an email to the user's
|
|
69
87
|
registered email address:
|
70
88
|
|
71
89
|
```ruby
|
72
|
-
class UserMailer <
|
90
|
+
class UserMailer < ApplicationMailer
|
73
91
|
default from: 'notifications@example.com'
|
74
92
|
|
75
93
|
def welcome_email(user)
|
@@ -84,8 +102,11 @@ Here is a quick explanation of the items presented in the preceding method. For
|
|
84
102
|
a full list of all available options, please have a look further down at the
|
85
103
|
Complete List of Action Mailer user-settable attributes section.
|
86
104
|
|
87
|
-
* `default Hash` - This is a hash of default values for any email you send from
|
88
|
-
|
105
|
+
* `default Hash` - This is a hash of default values for any email you send from
|
106
|
+
this mailer. In this case we are setting the `:from` header to a value for all
|
107
|
+
messages in this class. This can be overridden on a per-email basis.
|
108
|
+
* `mail` - The actual email message, we are passing the `:to` and `:subject`
|
109
|
+
headers in.
|
89
110
|
|
90
111
|
Just like controllers, any instance variables we define in the method become
|
91
112
|
available for use in the views.
|
@@ -105,7 +126,7 @@ will be the template used for the email, formatted in HTML:
|
|
105
126
|
<h1>Welcome to example.com, <%= @user.name %></h1>
|
106
127
|
<p>
|
107
128
|
You have successfully signed up to example.com,
|
108
|
-
your username is: <%= @user.login %>.<br
|
129
|
+
your username is: <%= @user.login %>.<br>
|
109
130
|
</p>
|
110
131
|
<p>
|
111
132
|
To login to the site, just follow this link: <%= @url %>.
|
@@ -138,7 +159,7 @@ When you call the `mail` method now, Action Mailer will detect the two templates
|
|
138
159
|
|
139
160
|
Mailers are really just another way to render a view. Instead of rendering a
|
140
161
|
view and sending out the HTTP protocol, they are just sending it out through the
|
141
|
-
|
162
|
+
email protocols instead. Due to this, it makes sense to just have your
|
142
163
|
controller tell the Mailer to send an email when a user is successfully created.
|
143
164
|
|
144
165
|
Setting this up is painfully simple.
|
@@ -146,14 +167,17 @@ Setting this up is painfully simple.
|
|
146
167
|
First, let's create a simple `User` scaffold:
|
147
168
|
|
148
169
|
```bash
|
149
|
-
$ rails generate scaffold user name email login
|
150
|
-
$ rake db:migrate
|
170
|
+
$ bin/rails generate scaffold user name email login
|
171
|
+
$ bin/rake db:migrate
|
151
172
|
```
|
152
173
|
|
153
174
|
Now that we have a user model to play with, we will just edit the
|
154
|
-
`app/controllers/users_controller.rb` make it instruct the UserMailer to deliver
|
175
|
+
`app/controllers/users_controller.rb` make it instruct the `UserMailer` to deliver
|
155
176
|
an email to the newly created user by editing the create action and inserting a
|
156
|
-
call to `UserMailer.welcome_email` right after the user is successfully saved
|
177
|
+
call to `UserMailer.welcome_email` right after the user is successfully saved.
|
178
|
+
|
179
|
+
Action Mailer is nicely integrated with Active Job so you can send emails outside
|
180
|
+
of the request-response cycle, so the user doesn't have to wait on it:
|
157
181
|
|
158
182
|
```ruby
|
159
183
|
class UsersController < ApplicationController
|
@@ -164,8 +188,8 @@ class UsersController < ApplicationController
|
|
164
188
|
|
165
189
|
respond_to do |format|
|
166
190
|
if @user.save
|
167
|
-
# Tell the UserMailer to send a welcome
|
168
|
-
UserMailer.welcome_email(@user).
|
191
|
+
# Tell the UserMailer to send a welcome email after save
|
192
|
+
UserMailer.welcome_email(@user).deliver_later
|
169
193
|
|
170
194
|
format.html { redirect_to(@user, notice: 'User was successfully created.') }
|
171
195
|
format.json { render json: @user, status: :created, location: @user }
|
@@ -178,8 +202,29 @@ class UsersController < ApplicationController
|
|
178
202
|
end
|
179
203
|
```
|
180
204
|
|
181
|
-
|
182
|
-
|
205
|
+
NOTE: Active Job's default behavior is to execute jobs ':inline'. So, you can use
|
206
|
+
`deliver_later` now to send emails, and when you later decide to start sending
|
207
|
+
them from a background job, you'll only need to set up Active Job to use a queueing
|
208
|
+
backend (Sidekiq, Resque, etc).
|
209
|
+
|
210
|
+
If you want to send emails right away (from a cronjob for example) just call
|
211
|
+
`deliver_now`:
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
class SendWeeklySummary
|
215
|
+
def run
|
216
|
+
User.find_each do |user|
|
217
|
+
UserMailer.weekly_summary(user).deliver_now
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
```
|
222
|
+
|
223
|
+
The method `welcome_email` returns a `ActionMailer::MessageDelivery` object which
|
224
|
+
can then just be told `deliver_now` or `deliver_later` to send itself out. The
|
225
|
+
`ActionMailer::MessageDelivery` object is just a wrapper around a `Mail::Message`. If
|
226
|
+
you want to inspect, alter or do anything else with the `Mail::Message` object you can
|
227
|
+
access it with the `message` method on the `ActionMailer::MessageDelivery` object.
|
183
228
|
|
184
229
|
### Auto encoding header values
|
185
230
|
|
@@ -216,6 +261,11 @@ Action Mailer makes it very easy to add attachments.
|
|
216
261
|
attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
|
217
262
|
```
|
218
263
|
|
264
|
+
When the `mail` method will be triggered, it will send a multipart email with
|
265
|
+
an attachment, properly nested with the top level being `multipart/mixed` and
|
266
|
+
the first part being a `multipart/alternative` containing the plain text and
|
267
|
+
HTML email messages.
|
268
|
+
|
219
269
|
NOTE: Mail will automatically Base64 encode an attachment. If you want something
|
220
270
|
different, encode your content and pass in the encoded content and encoding in a
|
221
271
|
`Hash` to the `attachments` method.
|
@@ -225,9 +275,11 @@ different, encode your content and pass in the encoded content and encoding in a
|
|
225
275
|
|
226
276
|
```ruby
|
227
277
|
encoded_content = SpecialEncode(File.read('/path/to/filename.jpg'))
|
228
|
-
attachments['filename.jpg'] = {
|
229
|
-
|
230
|
-
|
278
|
+
attachments['filename.jpg'] = {
|
279
|
+
mime_type: 'application/x-gzip',
|
280
|
+
encoding: 'SpecialEncoding',
|
281
|
+
content: encoded_content
|
282
|
+
}
|
231
283
|
```
|
232
284
|
|
233
285
|
NOTE: If you specify an encoding, Mail will assume that your content is already
|
@@ -261,8 +313,7 @@ Action Mailer 3.0 makes inline attachments, which involved a lot of hacking in p
|
|
261
313
|
```html+erb
|
262
314
|
<p>Hello there, this is our image</p>
|
263
315
|
|
264
|
-
<%= image_tag attachments['image.jpg'].url, alt: 'My Photo',
|
265
|
-
class: 'photos' %>
|
316
|
+
<%= image_tag attachments['image.jpg'].url, alt: 'My Photo', class: 'photos' %>
|
266
317
|
```
|
267
318
|
|
268
319
|
#### Sending Email To Multiple Recipients
|
@@ -296,7 +347,7 @@ email address in the format `"Full Name <email>"`.
|
|
296
347
|
```ruby
|
297
348
|
def welcome_email(user)
|
298
349
|
@user = user
|
299
|
-
email_with_name = "#{@user.name} <#{@user.email}>
|
350
|
+
email_with_name = %("#{@user.name}" <#{@user.email}>)
|
300
351
|
mail(to: email_with_name, subject: 'Welcome to My Awesome Site')
|
301
352
|
end
|
302
353
|
```
|
@@ -312,7 +363,7 @@ for the HTML version and `welcome_email.text.erb` for the plain text version.
|
|
312
363
|
To change the default mailer view for your action you do something like:
|
313
364
|
|
314
365
|
```ruby
|
315
|
-
class UserMailer <
|
366
|
+
class UserMailer < ApplicationMailer
|
316
367
|
default from: 'notifications@example.com'
|
317
368
|
|
318
369
|
def welcome_email(user)
|
@@ -334,7 +385,7 @@ If you want more flexibility you can also pass a block and render specific
|
|
334
385
|
templates or even render inline or text without using a template file:
|
335
386
|
|
336
387
|
```ruby
|
337
|
-
class UserMailer <
|
388
|
+
class UserMailer < ApplicationMailer
|
338
389
|
default from: 'notifications@example.com'
|
339
390
|
|
340
391
|
def welcome_email(user)
|
@@ -364,7 +415,7 @@ layout.
|
|
364
415
|
In order to use a different file, call `layout` in your mailer:
|
365
416
|
|
366
417
|
```ruby
|
367
|
-
class UserMailer <
|
418
|
+
class UserMailer < ApplicationMailer
|
368
419
|
layout 'awesome' # use awesome.(html|text).erb as the layout
|
369
420
|
end
|
370
421
|
```
|
@@ -373,10 +424,10 @@ Just like with controller views, use `yield` to render the view inside the
|
|
373
424
|
layout.
|
374
425
|
|
375
426
|
You can also pass in a `layout: 'layout_name'` option to the render call inside
|
376
|
-
the format block to specify different layouts for different
|
427
|
+
the format block to specify different layouts for different formats:
|
377
428
|
|
378
429
|
```ruby
|
379
|
-
class UserMailer <
|
430
|
+
class UserMailer < ApplicationMailer
|
380
431
|
def welcome_email(user)
|
381
432
|
mail(to: user.email) do |format|
|
382
433
|
format.html { render layout: 'my_layout' }
|
@@ -401,6 +452,22 @@ globally in `config/application.rb`:
|
|
401
452
|
config.action_mailer.default_url_options = { host: 'example.com' }
|
402
453
|
```
|
403
454
|
|
455
|
+
Because of this behavior you cannot use any of the `*_path` helpers inside of
|
456
|
+
an email. Instead you will need to use the associated `*_url` helper. For example
|
457
|
+
instead of using
|
458
|
+
|
459
|
+
```
|
460
|
+
<%= link_to 'welcome', welcome_path %>
|
461
|
+
```
|
462
|
+
|
463
|
+
You will need to use:
|
464
|
+
|
465
|
+
```
|
466
|
+
<%= link_to 'welcome', welcome_url %>
|
467
|
+
```
|
468
|
+
|
469
|
+
By using the full URL, your links will now work in your emails.
|
470
|
+
|
404
471
|
#### generating URLs with `url_for`
|
405
472
|
|
406
473
|
You need to pass the `only_path: false` option when using `url_for`. This will
|
@@ -440,6 +507,9 @@ url helper.
|
|
440
507
|
<%= user_url(@user, host: 'example.com') %>
|
441
508
|
```
|
442
509
|
|
510
|
+
NOTE: non-`GET` links require [jQuery UJS](https://github.com/rails/jquery-ujs)
|
511
|
+
and won't work in mailer templates. They will result in normal `GET` requests.
|
512
|
+
|
443
513
|
### Sending Multipart Emails
|
444
514
|
|
445
515
|
Action Mailer will automatically send multipart emails if you have different
|
@@ -451,26 +521,6 @@ with the HTML and text versions setup as different parts.
|
|
451
521
|
The order of the parts getting inserted is determined by the `:parts_order`
|
452
522
|
inside of the `ActionMailer::Base.default` method.
|
453
523
|
|
454
|
-
### Sending Emails with Attachments
|
455
|
-
|
456
|
-
Attachments can be added by using the `attachments` method:
|
457
|
-
|
458
|
-
```ruby
|
459
|
-
class UserMailer < ActionMailer::Base
|
460
|
-
def welcome_email(user)
|
461
|
-
@user = user
|
462
|
-
@url = user_url(@user)
|
463
|
-
attachments['terms.pdf'] = File.read('/path/terms.pdf')
|
464
|
-
mail(to: @user.email,
|
465
|
-
subject: 'Please see the Terms and Conditions attached')
|
466
|
-
end
|
467
|
-
end
|
468
|
-
```
|
469
|
-
|
470
|
-
The above will send a multipart email with an attachment, properly nested with
|
471
|
-
the top level being `multipart/mixed` and the first part being a
|
472
|
-
`multipart/alternative` containing the plain text and HTML email messages.
|
473
|
-
|
474
524
|
### Sending Emails with Dynamic Delivery Options
|
475
525
|
|
476
526
|
If you wish to override the default delivery options (e.g. SMTP credentials)
|
@@ -478,7 +528,7 @@ while delivering emails, you can do this using `delivery_method_options` in the
|
|
478
528
|
mailer action.
|
479
529
|
|
480
530
|
```ruby
|
481
|
-
class UserMailer <
|
531
|
+
class UserMailer < ApplicationMailer
|
482
532
|
def welcome_email(user, company)
|
483
533
|
@user = user
|
484
534
|
@url = user_url(@user)
|
@@ -496,11 +546,11 @@ end
|
|
496
546
|
|
497
547
|
There may be cases in which you want to skip the template rendering step and
|
498
548
|
supply the email body as a string. You can achieve this using the `:body`
|
499
|
-
option.
|
549
|
+
option. In such cases don't forget to add the `:content_type` option. Rails
|
500
550
|
will default to `text/plain` otherwise.
|
501
551
|
|
502
552
|
```ruby
|
503
|
-
class UserMailer <
|
553
|
+
class UserMailer < ApplicationMailer
|
504
554
|
def welcome_email(user, email_body)
|
505
555
|
mail(to: user.email,
|
506
556
|
body: email_body,
|
@@ -530,9 +580,9 @@ mailer, and pass the email object to the mailer `receive` instance
|
|
530
580
|
method. Here's an example:
|
531
581
|
|
532
582
|
```ruby
|
533
|
-
class UserMailer <
|
583
|
+
class UserMailer < ApplicationMailer
|
534
584
|
def receive(email)
|
535
|
-
page = Page.
|
585
|
+
page = Page.find_by(address: email.to.first)
|
536
586
|
page.emails.create(
|
537
587
|
subject: email.subject,
|
538
588
|
body: email.body
|
@@ -566,7 +616,7 @@ Action Mailer allows for you to specify a `before_action`, `after_action` and
|
|
566
616
|
using instance variables set in your mailer action.
|
567
617
|
|
568
618
|
```ruby
|
569
|
-
class UserMailer <
|
619
|
+
class UserMailer < ApplicationMailer
|
570
620
|
after_action :set_delivery_options,
|
571
621
|
:prevent_delivery_to_guests,
|
572
622
|
:set_business_headers
|
@@ -584,25 +634,25 @@ class UserMailer < ActionMailer::Base
|
|
584
634
|
|
585
635
|
private
|
586
636
|
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
637
|
+
def set_delivery_options
|
638
|
+
# You have access to the mail instance,
|
639
|
+
# @business and @user instance variables here
|
640
|
+
if @business && @business.has_smtp_settings?
|
641
|
+
mail.delivery_method.settings.merge!(@business.smtp_settings)
|
642
|
+
end
|
592
643
|
end
|
593
|
-
end
|
594
644
|
|
595
|
-
|
596
|
-
|
597
|
-
|
645
|
+
def prevent_delivery_to_guests
|
646
|
+
if @user && @user.guest?
|
647
|
+
mail.perform_deliveries = false
|
648
|
+
end
|
598
649
|
end
|
599
|
-
end
|
600
650
|
|
601
|
-
|
602
|
-
|
603
|
-
|
651
|
+
def set_business_headers
|
652
|
+
if @business
|
653
|
+
headers["X-SMTPAPI-CATEGORY"] = @business.code
|
654
|
+
end
|
604
655
|
end
|
605
|
-
end
|
606
656
|
end
|
607
657
|
```
|
608
658
|
|
@@ -623,16 +673,16 @@ files (environment.rb, production.rb, etc...)
|
|
623
673
|
| Configuration | Description |
|
624
674
|
|---------------|-------------|
|
625
675
|
|`logger`|Generates information on the mailing run if available. Can be set to `nil` for no logging. Compatible with both Ruby's own `Logger` and `Log4r` loggers.|
|
626
|
-
|`smtp_settings`|Allows detailed configuration for `:smtp` delivery method:<ul><li>`:address` - Allows you to use a remote mail server. Just change it from its default "localhost" setting.</li><li>`:port`
|
676
|
+
|`smtp_settings`|Allows detailed configuration for `:smtp` delivery method:<ul><li>`:address` - Allows you to use a remote mail server. Just change it from its default `"localhost"` setting.</li><li>`:port` - On the off chance that your mail server doesn't run on port 25, you can change it.</li><li>`:domain` - If you need to specify a HELO domain, you can do it here.</li><li>`:user_name` - If your mail server requires authentication, set the username in this setting.</li><li>`:password` - If your mail server requires authentication, set the password in this setting.</li><li>`:authentication` - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of `:plain` (will send the password in the clear), `:login` (will send password Base64 encoded) or `:cram_md5` (combines a Challenge/Response mechanism to exchange information and a cryptographic Message Digest 5 algorithm to hash important information)</li><li>`:enable_starttls_auto` - Detects if STARTTLS is enabled in your SMTP server and starts to use it. Defaults to `true`.</li><li>`:openssl_verify_mode` - When using TLS, you can set how OpenSSL checks the certificate. This is really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name of an OpenSSL verify constant ('none', 'peer', 'client_once', 'fail_if_no_peer_cert') or directly the constant (`OpenSSL::SSL::VERIFY_NONE`, `OpenSSL::SSL::VERIFY_PEER`, ...).</li></ul>|
|
627
677
|
|`sendmail_settings`|Allows you to override options for the `:sendmail` delivery method.<ul><li>`:location` - The location of the sendmail executable. Defaults to `/usr/sbin/sendmail`.</li><li>`:arguments` - The command line arguments to be passed to sendmail. Defaults to `-i -t`.</li></ul>|
|
628
678
|
|`raise_delivery_errors`|Whether or not errors should be raised if the email fails to be delivered. This only works if the external email server is configured for immediate delivery.|
|
629
|
-
|`delivery_method`|Defines a delivery method. Possible values are
|
679
|
+
|`delivery_method`|Defines a delivery method. Possible values are:<ul><li>`:smtp` (default), can be configured by using `config.action_mailer.smtp_settings`.</li><li>`:sendmail`, can be configured by using `config.action_mailer.sendmail_settings`.</li><li>`:file`: save emails to files; can be configured by using `config.action_mailer.file_settings`.</li><li>`:test`: save emails to `ActionMailer::Base.deliveries` array.</li></ul>See [API docs](http://api.rubyonrails.org/classes/ActionMailer/Base.html) for more info.|
|
630
680
|
|`perform_deliveries`|Determines whether deliveries are actually carried out when the `deliver` method is invoked on the Mail message. By default they are, but this can be turned off to help functional testing.|
|
631
681
|
|`deliveries`|Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.|
|
632
682
|
|`default_options`|Allows you to set default values for the `mail` method options (`:from`, `:reply_to`, etc.).|
|
633
683
|
|
634
684
|
For a complete writeup of possible configurations see the
|
635
|
-
[Action Mailer
|
685
|
+
[Configuring Action Mailer](configuring.html#configuring-action-mailer) in
|
636
686
|
our Configuring Rails Applications guide.
|
637
687
|
|
638
688
|
### Example Action Mailer Configuration
|
@@ -649,13 +699,13 @@ config.action_mailer.delivery_method = :sendmail
|
|
649
699
|
# }
|
650
700
|
config.action_mailer.perform_deliveries = true
|
651
701
|
config.action_mailer.raise_delivery_errors = true
|
652
|
-
config.action_mailer.default_options = {from: 'no-
|
702
|
+
config.action_mailer.default_options = {from: 'no-reply@example.com'}
|
653
703
|
```
|
654
704
|
|
655
705
|
### Action Mailer Configuration for Gmail
|
656
706
|
|
657
|
-
As Action Mailer now uses the Mail gem, this
|
658
|
-
`config/environments/$RAILS_ENV.rb` file:
|
707
|
+
As Action Mailer now uses the [Mail gem](https://github.com/mikel/mail), this
|
708
|
+
becomes as simple as adding to your `config/environments/$RAILS_ENV.rb` file:
|
659
709
|
|
660
710
|
```ruby
|
661
711
|
config.action_mailer.delivery_method = :smtp
|
@@ -677,6 +727,7 @@ You can find detailed instructions on how to test your mailers in the
|
|
677
727
|
|
678
728
|
Intercepting Emails
|
679
729
|
-------------------
|
730
|
+
|
680
731
|
There are situations where you need to edit an email before it's
|
681
732
|
delivered. Fortunately Action Mailer provides hooks to intercept every
|
682
733
|
email. You can register an interceptor to make modifications to mail messages
|
@@ -695,10 +746,12 @@ Mailer framework. You can do this in an initializer file
|
|
695
746
|
`config/initializers/sandbox_email_interceptor.rb`
|
696
747
|
|
697
748
|
```ruby
|
698
|
-
|
749
|
+
if Rails.env.staging?
|
750
|
+
ActionMailer::Base.register_interceptor(SandboxEmailInterceptor)
|
751
|
+
end
|
699
752
|
```
|
700
753
|
|
701
754
|
NOTE: The example above uses a custom environment called "staging" for a
|
702
755
|
production like server but for testing purposes. You can read
|
703
|
-
[Creating Rails environments](
|
756
|
+
[Creating Rails environments](configuring.html#creating-rails-environments)
|
704
757
|
for more information about custom Rails environments.
|
@@ -7,7 +7,6 @@ After reading this guide, you will know:
|
|
7
7
|
* How best to use templates, partials, and layouts.
|
8
8
|
* What helpers are provided by Action View and how to make your own.
|
9
9
|
* How to use localized views.
|
10
|
-
* How to use Action View outside of Rails.
|
11
10
|
|
12
11
|
--------------------------------------------------------------------------------
|
13
12
|
|
@@ -28,34 +27,34 @@ For each controller there is an associated directory in the `app/views` director
|
|
28
27
|
Let's take a look at what Rails does by default when creating a new resource using the scaffold generator:
|
29
28
|
|
30
29
|
```bash
|
31
|
-
$ rails generate scaffold
|
30
|
+
$ bin/rails generate scaffold article
|
32
31
|
[...]
|
33
32
|
invoke scaffold_controller
|
34
|
-
create app/controllers/
|
33
|
+
create app/controllers/articles_controller.rb
|
35
34
|
invoke erb
|
36
|
-
create app/views/
|
37
|
-
create app/views/
|
38
|
-
create app/views/
|
39
|
-
create app/views/
|
40
|
-
create app/views/
|
41
|
-
create app/views/
|
35
|
+
create app/views/articles
|
36
|
+
create app/views/articles/index.html.erb
|
37
|
+
create app/views/articles/edit.html.erb
|
38
|
+
create app/views/articles/show.html.erb
|
39
|
+
create app/views/articles/new.html.erb
|
40
|
+
create app/views/articles/_form.html.erb
|
42
41
|
[...]
|
43
42
|
```
|
44
43
|
|
45
44
|
There is a naming convention for views in Rails. Typically, the views share their name with the associated controller action, as you can see above.
|
46
|
-
For example, the index controller action of the `
|
47
|
-
The complete HTML returned to the client is composed of a combination of this ERB file, a layout template that wraps it, and all the partials that the view may reference.
|
45
|
+
For example, the index controller action of the `articles_controller.rb` will use the `index.html.erb` view file in the `app/views/articles` directory.
|
46
|
+
The complete HTML returned to the client is composed of a combination of this ERB file, a layout template that wraps it, and all the partials that the view may reference. Within this guide you will find more detailed documentation about each of these three components.
|
48
47
|
|
49
48
|
|
50
49
|
Templates, Partials and Layouts
|
51
50
|
-------------------------------
|
52
51
|
|
53
|
-
As mentioned
|
54
|
-
Below is a brief overview of each
|
52
|
+
As mentioned, the final HTML output is a composition of three Rails elements: `Templates`, `Partials` and `Layouts`.
|
53
|
+
Below is a brief overview of each of them.
|
55
54
|
|
56
55
|
### Templates
|
57
56
|
|
58
|
-
Action View templates can be written in several ways. If the template file has a `.erb` extension then it uses a mixture of ERB (
|
57
|
+
Action View templates can be written in several ways. If the template file has a `.erb` extension then it uses a mixture of ERB (Embedded Ruby) and HTML. If the template file has a `.builder` extension then the `Builder::XmlMarkup` library is used.
|
59
58
|
|
60
59
|
Rails supports multiple template systems and uses a file extension to distinguish amongst them. For example, an HTML file using the ERB template system will have `.html.erb` as a file extension.
|
61
60
|
|
@@ -68,11 +67,11 @@ Consider the following loop for names:
|
|
68
67
|
```html+erb
|
69
68
|
<h1>Names of all the people</h1>
|
70
69
|
<% @people.each do |person| %>
|
71
|
-
Name: <%= person.name %><br
|
70
|
+
Name: <%= person.name %><br>
|
72
71
|
<% end %>
|
73
72
|
```
|
74
73
|
|
75
|
-
The loop is set up
|
74
|
+
The loop is set up using regular embedding tags (`<% %>`) and the name is inserted using the output embedding tags (`<%= %>`). Note that this is not just a usage suggestion: regular output functions such as `print` and `puts` won't be rendered to the view with ERB templates. So this would be wrong:
|
76
75
|
|
77
76
|
```html+erb
|
78
77
|
<%# WRONG %>
|
@@ -152,7 +151,7 @@ By default, Rails will compile each template to a method in order to render it.
|
|
152
151
|
|
153
152
|
### Partials
|
154
153
|
|
155
|
-
Partial templates
|
154
|
+
Partial templates - usually just called "partials" - are another device for breaking the rendering process into more manageable chunks. With partials, you can extract pieces of code from your templates to separate files and also reuse them throughout your templates.
|
156
155
|
|
157
156
|
#### Naming Partials
|
158
157
|
|
@@ -231,7 +230,7 @@ The `object` and `as` options can also be used together:
|
|
231
230
|
|
232
231
|
#### Rendering Collections
|
233
232
|
|
234
|
-
It is very common that a template
|
233
|
+
It is very common that a template will need to iterate over a collection and render a sub-template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders a partial for each one of the elements in the array.
|
235
234
|
|
236
235
|
So this example for rendering all the products:
|
237
236
|
|
@@ -247,7 +246,7 @@ can be rewritten in a single line:
|
|
247
246
|
<%= render partial: "product", collection: @products %>
|
248
247
|
```
|
249
248
|
|
250
|
-
When a partial is called
|
249
|
+
When a partial is called with a collection, the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial. In this case, the partial is `_product`, and within it you can refer to `product` to get the collection member that is being rendered.
|
251
250
|
|
252
251
|
You can use a shorthand syntax for rendering collections. Assuming `@products` is a collection of `Product` instances, you can simply write the following to produce the same result:
|
253
252
|
|
@@ -255,44 +254,44 @@ You can use a shorthand syntax for rendering collections. Assuming `@products` i
|
|
255
254
|
<%= render @products %>
|
256
255
|
```
|
257
256
|
|
258
|
-
Rails determines the name of the partial to use by looking at the model name in the collection, `Product` in this case. In fact, you can even
|
257
|
+
Rails determines the name of the partial to use by looking at the model name in the collection, `Product` in this case. In fact, you can even render a collection made up of instances of different models using this shorthand, and Rails will choose the proper partial for each member of the collection.
|
259
258
|
|
260
259
|
#### Spacer Templates
|
261
260
|
|
262
261
|
You can also specify a second partial to be rendered between instances of the main partial by using the `:spacer_template` option:
|
263
262
|
|
264
263
|
```erb
|
265
|
-
<%= render @products, spacer_template: "product_ruler" %>
|
264
|
+
<%= render partial: @products, spacer_template: "product_ruler" %>
|
266
265
|
```
|
267
266
|
|
268
267
|
Rails will render the `_product_ruler` partial (with no data passed to it) between each pair of `_product` partials.
|
269
268
|
|
270
269
|
### Layouts
|
271
270
|
|
272
|
-
Layouts can be used to render a common view template around the results of Rails controller actions. Typically,
|
271
|
+
Layouts can be used to render a common view template around the results of Rails controller actions. Typically, a Rails application will have a couple of layouts that pages will be rendered within. For example, a site might have one layout for a logged in user and another for the marketing or sales side of the site. The logged in user layout might include top-level navigation that should be present across many controller actions. The sales layout for a SaaS app might include top-level navigation for things like "Pricing" and "Contact Us" pages. You would expect each layout to have a different look and feel. You can read about layouts in more detail in the [Layouts and Rendering in Rails](layouts_and_rendering.html) guide.
|
273
272
|
|
274
273
|
Partial Layouts
|
275
274
|
---------------
|
276
275
|
|
277
|
-
Partials can have their own layouts applied to them. These layouts are different
|
276
|
+
Partials can have their own layouts applied to them. These layouts are different from those applied to a controller action, but they work in a similar fashion.
|
278
277
|
|
279
|
-
Let's say we're displaying
|
278
|
+
Let's say we're displaying an article on a page which should be wrapped in a `div` for display purposes. Firstly, we'll create a new `Article`:
|
280
279
|
|
281
280
|
```ruby
|
282
|
-
|
281
|
+
Article.create(body: 'Partial Layouts are cool!')
|
283
282
|
```
|
284
283
|
|
285
|
-
In the `show` template, we'll render the `
|
284
|
+
In the `show` template, we'll render the `_article` partial wrapped in the `box` layout:
|
286
285
|
|
287
|
-
**
|
286
|
+
**articles/show.html.erb**
|
288
287
|
|
289
288
|
```erb
|
290
|
-
<%= render partial: '
|
289
|
+
<%= render partial: 'article', layout: 'box', locals: {article: @article} %>
|
291
290
|
```
|
292
291
|
|
293
|
-
The `box` layout simply wraps the `
|
292
|
+
The `box` layout simply wraps the `_article` partial in a `div`:
|
294
293
|
|
295
|
-
**
|
294
|
+
**articles/_box.html.erb**
|
296
295
|
|
297
296
|
```html+erb
|
298
297
|
<div class='box'>
|
@@ -300,13 +299,13 @@ The `box` layout simply wraps the `_post` partial in a `div`:
|
|
300
299
|
</div>
|
301
300
|
```
|
302
301
|
|
303
|
-
The `
|
302
|
+
The `_article` partial wraps the article's `body` in a `div` with the `id` of the article using the `div_for` helper:
|
304
303
|
|
305
|
-
**
|
304
|
+
**articles/_article.html.erb**
|
306
305
|
|
307
306
|
```html+erb
|
308
|
-
<%= div_for(
|
309
|
-
<p><%=
|
307
|
+
<%= div_for(article) do %>
|
308
|
+
<p><%= article.body %></p>
|
310
309
|
<% end %>
|
311
310
|
```
|
312
311
|
|
@@ -314,22 +313,22 @@ this would output the following:
|
|
314
313
|
|
315
314
|
```html
|
316
315
|
<div class='box'>
|
317
|
-
<div id='
|
316
|
+
<div id='article_1'>
|
318
317
|
<p>Partial Layouts are cool!</p>
|
319
318
|
</div>
|
320
319
|
</div>
|
321
320
|
```
|
322
321
|
|
323
|
-
Note that the partial layout has access to the local `
|
322
|
+
Note that the partial layout has access to the local `article` variable that was passed into the `render` call. However, unlike application-wide layouts, partial layouts still have the underscore prefix.
|
324
323
|
|
325
|
-
You can also render a block of code within a partial layout instead of calling `yield`. For example, if we didn't have the `
|
324
|
+
You can also render a block of code within a partial layout instead of calling `yield`. For example, if we didn't have the `_article` partial, we could do this instead:
|
326
325
|
|
327
|
-
**
|
326
|
+
**articles/show.html.erb**
|
328
327
|
|
329
328
|
```html+erb
|
330
|
-
<% render(layout: 'box', locals: {
|
331
|
-
<%= div_for(
|
332
|
-
<p><%=
|
329
|
+
<% render(layout: 'box', locals: {article: @article}) do %>
|
330
|
+
<%= div_for(article) do %>
|
331
|
+
<p><%= article.body %></p>
|
333
332
|
<% end %>
|
334
333
|
<% end %>
|
335
334
|
```
|
@@ -356,18 +355,18 @@ This module provides methods for generating container tags, such as `div`, for y
|
|
356
355
|
|
357
356
|
Renders a container tag that relates to your Active Record Object.
|
358
357
|
|
359
|
-
For example, given `@
|
358
|
+
For example, given `@article` is the object of `Article` class, you can do:
|
360
359
|
|
361
360
|
```html+erb
|
362
|
-
<%= content_tag_for(:tr, @
|
363
|
-
<td><%= @
|
361
|
+
<%= content_tag_for(:tr, @article) do %>
|
362
|
+
<td><%= @article.title %></td>
|
364
363
|
<% end %>
|
365
364
|
```
|
366
365
|
|
367
366
|
This will generate this HTML output:
|
368
367
|
|
369
368
|
```html
|
370
|
-
<tr id="
|
369
|
+
<tr id="article_1234" class="article">
|
371
370
|
<td>Hello World!</td>
|
372
371
|
</tr>
|
373
372
|
```
|
@@ -375,34 +374,34 @@ This will generate this HTML output:
|
|
375
374
|
You can also supply HTML attributes as an additional option hash. For example:
|
376
375
|
|
377
376
|
```html+erb
|
378
|
-
<%= content_tag_for(:tr, @
|
379
|
-
<td><%= @
|
377
|
+
<%= content_tag_for(:tr, @article, class: "frontpage") do %>
|
378
|
+
<td><%= @article.title %></td>
|
380
379
|
<% end %>
|
381
380
|
```
|
382
381
|
|
383
382
|
Will generate this HTML output:
|
384
383
|
|
385
384
|
```html
|
386
|
-
<tr id="
|
385
|
+
<tr id="article_1234" class="article frontpage">
|
387
386
|
<td>Hello World!</td>
|
388
387
|
</tr>
|
389
388
|
```
|
390
389
|
|
391
|
-
You can pass a collection of Active Record objects. This method will loop through your objects and create a container for each of them. For example, given `@
|
390
|
+
You can pass a collection of Active Record objects. This method will loop through your objects and create a container for each of them. For example, given `@articles` is an array of two `Article` objects:
|
392
391
|
|
393
392
|
```html+erb
|
394
|
-
<%= content_tag_for(:tr, @
|
395
|
-
<td><%=
|
393
|
+
<%= content_tag_for(:tr, @articles) do |article| %>
|
394
|
+
<td><%= article.title %></td>
|
396
395
|
<% end %>
|
397
396
|
```
|
398
397
|
|
399
398
|
Will generate this HTML output:
|
400
399
|
|
401
400
|
```html
|
402
|
-
<tr id="
|
401
|
+
<tr id="article_1234" class="article">
|
403
402
|
<td>Hello World!</td>
|
404
403
|
</tr>
|
405
|
-
<tr id="
|
404
|
+
<tr id="article_1235" class="article">
|
406
405
|
<td>Ruby on Rails Rocks!</td>
|
407
406
|
</tr>
|
408
407
|
```
|
@@ -412,15 +411,15 @@ Will generate this HTML output:
|
|
412
411
|
This is actually a convenient method which calls `content_tag_for` internally with `:div` as the tag name. You can pass either an Active Record object or a collection of objects. For example:
|
413
412
|
|
414
413
|
```html+erb
|
415
|
-
<%= div_for(@
|
416
|
-
<td><%= @
|
414
|
+
<%= div_for(@article, class: "frontpage") do %>
|
415
|
+
<td><%= @article.title %></td>
|
417
416
|
<% end %>
|
418
417
|
```
|
419
418
|
|
420
419
|
Will generate this HTML output:
|
421
420
|
|
422
421
|
```html
|
423
|
-
<div id="
|
422
|
+
<div id="article_1234" class="article frontpage">
|
424
423
|
<td>Hello World!</td>
|
425
424
|
</div>
|
426
425
|
```
|
@@ -436,39 +435,13 @@ config.action_controller.asset_host = "assets.example.com"
|
|
436
435
|
image_tag("rails.png") # => <img src="http://assets.example.com/images/rails.png" alt="Rails" />
|
437
436
|
```
|
438
437
|
|
439
|
-
#### register_javascript_expansion
|
440
|
-
|
441
|
-
Register one or more JavaScript files to be included when symbol is passed to javascript_include_tag. This method is typically intended to be called from plugin initialization to register JavaScript files that the plugin installed in `vendor/assets/javascripts`.
|
442
|
-
|
443
|
-
```ruby
|
444
|
-
ActionView::Helpers::AssetTagHelper.register_javascript_expansion monkey: ["head", "body", "tail"]
|
445
|
-
|
446
|
-
javascript_include_tag :monkey # =>
|
447
|
-
<script src="/assets/head.js"></script>
|
448
|
-
<script src="/assets/body.js"></script>
|
449
|
-
<script src="/assets/tail.js"></script>
|
450
|
-
```
|
451
|
-
|
452
|
-
#### register_stylesheet_expansion
|
453
|
-
|
454
|
-
Register one or more stylesheet files to be included when symbol is passed to `stylesheet_link_tag`. This method is typically intended to be called from plugin initialization to register stylesheet files that the plugin installed in `vendor/assets/stylesheets`.
|
455
|
-
|
456
|
-
```ruby
|
457
|
-
ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion monkey: ["head", "body", "tail"]
|
458
|
-
|
459
|
-
stylesheet_link_tag :monkey # =>
|
460
|
-
<link href="/assets/head.css" media="screen" rel="stylesheet" />
|
461
|
-
<link href="/assets/body.css" media="screen" rel="stylesheet" />
|
462
|
-
<link href="/assets/tail.css" media="screen" rel="stylesheet" />
|
463
|
-
```
|
464
|
-
|
465
438
|
#### auto_discovery_link_tag
|
466
439
|
|
467
|
-
Returns a link tag that browsers and
|
440
|
+
Returns a link tag that browsers and feed readers can use to auto-detect an RSS or Atom feed.
|
468
441
|
|
469
442
|
```ruby
|
470
|
-
auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {title: "RSS Feed"}) # =>
|
471
|
-
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://www.example.com/feed" />
|
443
|
+
auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", { title: "RSS Feed" }) # =>
|
444
|
+
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://www.example.com/feed.rss" />
|
472
445
|
```
|
473
446
|
|
474
447
|
#### image_path
|
@@ -495,7 +468,7 @@ image_url("edit.png") # => http://www.example.com/assets/edit.png
|
|
495
468
|
|
496
469
|
#### image_tag
|
497
470
|
|
498
|
-
Returns an
|
471
|
+
Returns an HTML image tag for the source. The source can be a full path or a file that exists in your `app/assets/images` directory.
|
499
472
|
|
500
473
|
```ruby
|
501
474
|
image_tag("icon.png") # => <img src="/assets/icon.png" alt="Icon" />
|
@@ -503,7 +476,7 @@ image_tag("icon.png") # => <img src="/assets/icon.png" alt="Icon" />
|
|
503
476
|
|
504
477
|
#### javascript_include_tag
|
505
478
|
|
506
|
-
Returns an
|
479
|
+
Returns an HTML script tag for each of the sources provided. You can pass in the filename (`.js` extension is optional) of JavaScript files that exist in your `app/assets/javascripts` directory for inclusion into the current page or you can pass the full path relative to your document root.
|
507
480
|
|
508
481
|
```ruby
|
509
482
|
javascript_include_tag "common" # => <script src="/assets/common.js"></script>
|
@@ -590,14 +563,14 @@ This helper makes building an Atom feed easy. Here's a full usage example:
|
|
590
563
|
**config/routes.rb**
|
591
564
|
|
592
565
|
```ruby
|
593
|
-
resources :
|
566
|
+
resources :articles
|
594
567
|
```
|
595
568
|
|
596
|
-
**app/controllers/
|
569
|
+
**app/controllers/articles_controller.rb**
|
597
570
|
|
598
571
|
```ruby
|
599
572
|
def index
|
600
|
-
@
|
573
|
+
@articles = Article.all
|
601
574
|
|
602
575
|
respond_to do |format|
|
603
576
|
format.html
|
@@ -606,20 +579,20 @@ def index
|
|
606
579
|
end
|
607
580
|
```
|
608
581
|
|
609
|
-
**app/views/
|
582
|
+
**app/views/articles/index.atom.builder**
|
610
583
|
|
611
584
|
```ruby
|
612
585
|
atom_feed do |feed|
|
613
|
-
feed.title("
|
614
|
-
feed.updated((@
|
586
|
+
feed.title("Articles Index")
|
587
|
+
feed.updated((@articles.first.created_at))
|
615
588
|
|
616
|
-
@
|
617
|
-
feed.entry(
|
618
|
-
entry.title(
|
619
|
-
entry.content(
|
589
|
+
@articles.each do |article|
|
590
|
+
feed.entry(article) do |entry|
|
591
|
+
entry.title(article.title)
|
592
|
+
entry.content(article.body, type: 'html')
|
620
593
|
|
621
594
|
entry.author do |author|
|
622
|
-
author.name(
|
595
|
+
author.name(article.author_name)
|
623
596
|
end
|
624
597
|
end
|
625
598
|
end
|
@@ -697,7 +670,7 @@ For example, let's say we have a standard application layout, but also a special
|
|
697
670
|
</html>
|
698
671
|
```
|
699
672
|
|
700
|
-
**app/views/
|
673
|
+
**app/views/articles/special.html.erb**
|
701
674
|
|
702
675
|
```html+erb
|
703
676
|
<p>This is a special page.</p>
|
@@ -714,7 +687,7 @@ For example, let's say we have a standard application layout, but also a special
|
|
714
687
|
Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based attribute.
|
715
688
|
|
716
689
|
```ruby
|
717
|
-
date_select("
|
690
|
+
date_select("article", "published_on")
|
718
691
|
```
|
719
692
|
|
720
693
|
#### datetime_select
|
@@ -722,7 +695,7 @@ date_select("post", "published_on")
|
|
722
695
|
Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a specified datetime-based attribute.
|
723
696
|
|
724
697
|
```ruby
|
725
|
-
datetime_select("
|
698
|
+
datetime_select("article", "published_on")
|
726
699
|
```
|
727
700
|
|
728
701
|
#### distance_of_time_in_words
|
@@ -736,7 +709,7 @@ distance_of_time_in_words(Time.now, Time.now + 15.seconds, include_seconds: true
|
|
736
709
|
|
737
710
|
#### select_date
|
738
711
|
|
739
|
-
Returns a set of
|
712
|
+
Returns a set of HTML select-tags (one for year, month, and day) pre-selected with the `date` provided.
|
740
713
|
|
741
714
|
```ruby
|
742
715
|
# Generates a date select that defaults to the date provided (six days after today)
|
@@ -748,7 +721,7 @@ select_date()
|
|
748
721
|
|
749
722
|
#### select_datetime
|
750
723
|
|
751
|
-
Returns a set of
|
724
|
+
Returns a set of HTML select-tags (one for year, month, day, hour, and minute) pre-selected with the `datetime` provided.
|
752
725
|
|
753
726
|
```ruby
|
754
727
|
# Generates a datetime select that defaults to the datetime provided (four days after today)
|
@@ -775,8 +748,8 @@ select_day(5)
|
|
775
748
|
Returns a select tag with options for each of the hours 0 through 23 with the current hour selected.
|
776
749
|
|
777
750
|
```ruby
|
778
|
-
# Generates a select field for
|
779
|
-
|
751
|
+
# Generates a select field for hours that defaults to the hours for the time provided
|
752
|
+
select_hour(Time.now + 6.hours)
|
780
753
|
```
|
781
754
|
|
782
755
|
#### select_minute
|
@@ -808,7 +781,7 @@ select_second(Time.now + 16.minutes)
|
|
808
781
|
|
809
782
|
#### select_time
|
810
783
|
|
811
|
-
Returns a set of
|
784
|
+
Returns a set of HTML select-tags (one for hour and minute).
|
812
785
|
|
813
786
|
```ruby
|
814
787
|
# Generates a time select that defaults to the time provided
|
@@ -904,10 +877,10 @@ The params hash has a nested person value, which can therefore be accessed with
|
|
904
877
|
Returns a checkbox tag tailored for accessing a specified attribute.
|
905
878
|
|
906
879
|
```ruby
|
907
|
-
# Let's say that @
|
908
|
-
check_box("
|
909
|
-
# => <input type="checkbox" id="
|
910
|
-
# <input name="
|
880
|
+
# Let's say that @article.validated? is 1:
|
881
|
+
check_box("article", "validated")
|
882
|
+
# => <input type="checkbox" id="article_validated" name="article[validated]" value="1" />
|
883
|
+
# <input name="article[validated]" type="hidden" value="0" />
|
911
884
|
```
|
912
885
|
|
913
886
|
#### fields_for
|
@@ -939,11 +912,11 @@ file_field(:user, :avatar)
|
|
939
912
|
Creates a form and a scope around a specific model object that is used as a base for questioning about values for the fields.
|
940
913
|
|
941
914
|
```html+erb
|
942
|
-
<%= form_for @
|
915
|
+
<%= form_for @article do |f| %>
|
943
916
|
<%= f.label :title, 'Title' %>:
|
944
|
-
<%= f.text_field :title %><br
|
917
|
+
<%= f.text_field :title %><br>
|
945
918
|
<%= f.label :body, 'Body' %>:
|
946
|
-
<%= f.text_area :body %><br
|
919
|
+
<%= f.text_area :body %><br>
|
947
920
|
<% end %>
|
948
921
|
```
|
949
922
|
|
@@ -961,8 +934,8 @@ hidden_field(:user, :token)
|
|
961
934
|
Returns a label tag tailored for labelling an input field for a specified attribute.
|
962
935
|
|
963
936
|
```ruby
|
964
|
-
label(:
|
965
|
-
# => <label for="
|
937
|
+
label(:article, :title)
|
938
|
+
# => <label for="article_title">Title</label>
|
966
939
|
```
|
967
940
|
|
968
941
|
#### password_field
|
@@ -979,11 +952,11 @@ password_field(:login, :pass)
|
|
979
952
|
Returns a radio button tag for accessing a specified attribute.
|
980
953
|
|
981
954
|
```ruby
|
982
|
-
# Let's say that @
|
983
|
-
radio_button("
|
984
|
-
radio_button("
|
985
|
-
# => <input type="radio" id="
|
986
|
-
# <input type="radio" id="
|
955
|
+
# Let's say that @article.category returns "rails":
|
956
|
+
radio_button("article", "category", "rails")
|
957
|
+
radio_button("article", "category", "java")
|
958
|
+
# => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
|
959
|
+
# <input type="radio" id="article_category_java" name="article[category]" value="java" />
|
987
960
|
```
|
988
961
|
|
989
962
|
#### text_area
|
@@ -1002,8 +975,26 @@ text_area(:comment, :text, size: "20x30")
|
|
1002
975
|
Returns an input tag of the "text" type tailored for accessing a specified attribute.
|
1003
976
|
|
1004
977
|
```ruby
|
1005
|
-
text_field(:
|
1006
|
-
# => <input type="text" id="
|
978
|
+
text_field(:article, :title)
|
979
|
+
# => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" />
|
980
|
+
```
|
981
|
+
|
982
|
+
#### email_field
|
983
|
+
|
984
|
+
Returns an input tag of the "email" type tailored for accessing a specified attribute.
|
985
|
+
|
986
|
+
```ruby
|
987
|
+
email_field(:user, :email)
|
988
|
+
# => <input type="email" id="user_email" name="user[email]" value="#{@user.email}" />
|
989
|
+
```
|
990
|
+
|
991
|
+
#### url_field
|
992
|
+
|
993
|
+
Returns an input tag of the "url" type tailored for accessing a specified attribute.
|
994
|
+
|
995
|
+
```ruby
|
996
|
+
url_field(:user, :url)
|
997
|
+
# => <input type="url" id="user_url" name="user[url]" value="#{@user.url}" />
|
1007
998
|
```
|
1008
999
|
|
1009
1000
|
### FormOptionsHelper
|
@@ -1017,28 +1008,28 @@ Returns `select` and `option` tags for the collection of existing return values
|
|
1017
1008
|
Example object structure for use with this method:
|
1018
1009
|
|
1019
1010
|
```ruby
|
1020
|
-
class
|
1011
|
+
class Article < ActiveRecord::Base
|
1021
1012
|
belongs_to :author
|
1022
1013
|
end
|
1023
1014
|
|
1024
1015
|
class Author < ActiveRecord::Base
|
1025
|
-
has_many :
|
1016
|
+
has_many :articles
|
1026
1017
|
def name_with_initial
|
1027
1018
|
"#{first_name.first}. #{last_name}"
|
1028
1019
|
end
|
1029
1020
|
end
|
1030
1021
|
```
|
1031
1022
|
|
1032
|
-
Sample usage (selecting the associated Author for an instance of
|
1023
|
+
Sample usage (selecting the associated Author for an instance of Article, `@article`):
|
1033
1024
|
|
1034
1025
|
```ruby
|
1035
|
-
collection_select(:
|
1026
|
+
collection_select(:article, :author_id, Author.all, :id, :name_with_initial, {prompt: true})
|
1036
1027
|
```
|
1037
1028
|
|
1038
|
-
If `@
|
1029
|
+
If `@article.author_id` is 1, this would return:
|
1039
1030
|
|
1040
1031
|
```html
|
1041
|
-
<select name="
|
1032
|
+
<select name="article[author_id]">
|
1042
1033
|
<option value="">Please select</option>
|
1043
1034
|
<option value="1" selected="selected">D. Heinemeier Hansson</option>
|
1044
1035
|
<option value="2">D. Thomas</option>
|
@@ -1053,33 +1044,33 @@ Returns `radio_button` tags for the collection of existing return values of `met
|
|
1053
1044
|
Example object structure for use with this method:
|
1054
1045
|
|
1055
1046
|
```ruby
|
1056
|
-
class
|
1047
|
+
class Article < ActiveRecord::Base
|
1057
1048
|
belongs_to :author
|
1058
1049
|
end
|
1059
1050
|
|
1060
1051
|
class Author < ActiveRecord::Base
|
1061
|
-
has_many :
|
1052
|
+
has_many :articles
|
1062
1053
|
def name_with_initial
|
1063
1054
|
"#{first_name.first}. #{last_name}"
|
1064
1055
|
end
|
1065
1056
|
end
|
1066
1057
|
```
|
1067
1058
|
|
1068
|
-
Sample usage (selecting the associated Author for an instance of
|
1059
|
+
Sample usage (selecting the associated Author for an instance of Article, `@article`):
|
1069
1060
|
|
1070
1061
|
```ruby
|
1071
|
-
collection_radio_buttons(:
|
1062
|
+
collection_radio_buttons(:article, :author_id, Author.all, :id, :name_with_initial)
|
1072
1063
|
```
|
1073
1064
|
|
1074
|
-
If `@
|
1065
|
+
If `@article.author_id` is 1, this would return:
|
1075
1066
|
|
1076
1067
|
```html
|
1077
|
-
<input id="
|
1078
|
-
<label for="
|
1079
|
-
<input id="
|
1080
|
-
<label for="
|
1081
|
-
<input id="
|
1082
|
-
<label for="
|
1068
|
+
<input id="article_author_id_1" name="article[author_id]" type="radio" value="1" checked="checked" />
|
1069
|
+
<label for="article_author_id_1">D. Heinemeier Hansson</label>
|
1070
|
+
<input id="article_author_id_2" name="article[author_id]" type="radio" value="2" />
|
1071
|
+
<label for="article_author_id_2">D. Thomas</label>
|
1072
|
+
<input id="article_author_id_3" name="article[author_id]" type="radio" value="3" />
|
1073
|
+
<label for="article_author_id_3">M. Clark</label>
|
1083
1074
|
```
|
1084
1075
|
|
1085
1076
|
#### collection_check_boxes
|
@@ -1089,44 +1080,36 @@ Returns `check_box` tags for the collection of existing return values of `method
|
|
1089
1080
|
Example object structure for use with this method:
|
1090
1081
|
|
1091
1082
|
```ruby
|
1092
|
-
class
|
1093
|
-
has_and_belongs_to_many :
|
1083
|
+
class Article < ActiveRecord::Base
|
1084
|
+
has_and_belongs_to_many :authors
|
1094
1085
|
end
|
1095
1086
|
|
1096
1087
|
class Author < ActiveRecord::Base
|
1097
|
-
has_and_belongs_to_many :
|
1088
|
+
has_and_belongs_to_many :articles
|
1098
1089
|
def name_with_initial
|
1099
1090
|
"#{first_name.first}. #{last_name}"
|
1100
1091
|
end
|
1101
1092
|
end
|
1102
1093
|
```
|
1103
1094
|
|
1104
|
-
Sample usage (selecting the associated Authors for an instance of
|
1095
|
+
Sample usage (selecting the associated Authors for an instance of Article, `@article`):
|
1105
1096
|
|
1106
1097
|
```ruby
|
1107
|
-
collection_check_boxes(:
|
1098
|
+
collection_check_boxes(:article, :author_ids, Author.all, :id, :name_with_initial)
|
1108
1099
|
```
|
1109
1100
|
|
1110
|
-
If `@
|
1101
|
+
If `@article.author_ids` is [1], this would return:
|
1111
1102
|
|
1112
1103
|
```html
|
1113
|
-
<input id="
|
1114
|
-
<label for="
|
1115
|
-
<input id="
|
1116
|
-
<label for="
|
1117
|
-
<input id="
|
1118
|
-
<label for="
|
1119
|
-
<input name="
|
1104
|
+
<input id="article_author_ids_1" name="article[author_ids][]" type="checkbox" value="1" checked="checked" />
|
1105
|
+
<label for="article_author_ids_1">D. Heinemeier Hansson</label>
|
1106
|
+
<input id="article_author_ids_2" name="article[author_ids][]" type="checkbox" value="2" />
|
1107
|
+
<label for="article_author_ids_2">D. Thomas</label>
|
1108
|
+
<input id="article_author_ids_3" name="article[author_ids][]" type="checkbox" value="3" />
|
1109
|
+
<label for="article_author_ids_3">M. Clark</label>
|
1110
|
+
<input name="article[author_ids][]" type="hidden" value="" />
|
1120
1111
|
```
|
1121
1112
|
|
1122
|
-
#### country_options_for_select
|
1123
|
-
|
1124
|
-
Returns a string of option tags for pretty much any country in the world.
|
1125
|
-
|
1126
|
-
#### country_select
|
1127
|
-
|
1128
|
-
Return select and option tags for the given object and method, using country_options_for_select to generate the list of option tags.
|
1129
|
-
|
1130
1113
|
#### option_groups_from_collection_for_select
|
1131
1114
|
|
1132
1115
|
Returns a string of `option` tags, like `options_from_collection_for_select`, but groups them by `optgroup` tags based on the object relationships of the arguments.
|
@@ -1204,13 +1187,13 @@ Create a select tag and a series of contained option tags for the provided objec
|
|
1204
1187
|
Example:
|
1205
1188
|
|
1206
1189
|
```ruby
|
1207
|
-
select("
|
1190
|
+
select("article", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {include_blank: true})
|
1208
1191
|
```
|
1209
1192
|
|
1210
|
-
If `@
|
1193
|
+
If `@article.person_id` is 1, this would become:
|
1211
1194
|
|
1212
1195
|
```html
|
1213
|
-
<select name="
|
1196
|
+
<select name="article[person_id]">
|
1214
1197
|
<option value=""></option>
|
1215
1198
|
<option value="1" selected="selected">David</option>
|
1216
1199
|
<option value="2">Sam</option>
|
@@ -1224,15 +1207,23 @@ Returns a string of option tags for pretty much any time zone in the world.
|
|
1224
1207
|
|
1225
1208
|
#### time_zone_select
|
1226
1209
|
|
1227
|
-
|
1210
|
+
Returns select and option tags for the given object and method, using `time_zone_options_for_select` to generate the list of option tags.
|
1228
1211
|
|
1229
1212
|
```ruby
|
1230
1213
|
time_zone_select( "user", "time_zone")
|
1231
1214
|
```
|
1232
1215
|
|
1216
|
+
#### date_field
|
1217
|
+
|
1218
|
+
Returns an input tag of the "date" type tailored for accessing a specified attribute.
|
1219
|
+
|
1220
|
+
```ruby
|
1221
|
+
date_field("user", "dob")
|
1222
|
+
```
|
1223
|
+
|
1233
1224
|
### FormTagHelper
|
1234
1225
|
|
1235
|
-
Provides a number of methods for creating form tags that
|
1226
|
+
Provides a number of methods for creating form tags that don't rely on an Active Record object assigned to the template like FormHelper does. Instead, you provide the names and values manually.
|
1236
1227
|
|
1237
1228
|
#### check_box_tag
|
1238
1229
|
|
@@ -1259,7 +1250,7 @@ Creates a field set for grouping HTML form elements.
|
|
1259
1250
|
Creates a file upload field.
|
1260
1251
|
|
1261
1252
|
```html+erb
|
1262
|
-
<%= form_tag
|
1253
|
+
<%= form_tag({action:"post"}, multipart: true) do %>
|
1263
1254
|
<label for="file">File to Upload</label> <%= file_field_tag "file" %>
|
1264
1255
|
<%= submit_tag %>
|
1265
1256
|
<% end %>
|
@@ -1277,10 +1268,10 @@ file_field_tag 'attachment'
|
|
1277
1268
|
Starts a form tag that points the action to an url configured with `url_for_options` just like `ActionController::Base#url_for`.
|
1278
1269
|
|
1279
1270
|
```html+erb
|
1280
|
-
<%= form_tag '/
|
1271
|
+
<%= form_tag '/articles' do %>
|
1281
1272
|
<div><%= submit_tag 'Save' %></div>
|
1282
1273
|
<% end %>
|
1283
|
-
# => <form action="/
|
1274
|
+
# => <form action="/articles" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>
|
1284
1275
|
```
|
1285
1276
|
|
1286
1277
|
#### hidden_field_tag
|
@@ -1342,8 +1333,8 @@ select_tag "people", "<option>David</option>"
|
|
1342
1333
|
Creates a submit button with the text provided as the caption.
|
1343
1334
|
|
1344
1335
|
```ruby
|
1345
|
-
submit_tag "Publish this
|
1346
|
-
# => <input name="commit" type="submit" value="Publish this
|
1336
|
+
submit_tag "Publish this article"
|
1337
|
+
# => <input name="commit" type="submit" value="Publish this article" />
|
1347
1338
|
```
|
1348
1339
|
|
1349
1340
|
#### text_area_tag
|
@@ -1351,8 +1342,8 @@ submit_tag "Publish this post"
|
|
1351
1342
|
Creates a text input area; use a textarea for longer text inputs such as blog posts or descriptions.
|
1352
1343
|
|
1353
1344
|
```ruby
|
1354
|
-
text_area_tag '
|
1355
|
-
# => <textarea id="
|
1345
|
+
text_area_tag 'article'
|
1346
|
+
# => <textarea id="article" name="article"></textarea>
|
1356
1347
|
```
|
1357
1348
|
|
1358
1349
|
#### text_field_tag
|
@@ -1364,25 +1355,36 @@ text_field_tag 'name'
|
|
1364
1355
|
# => <input id="name" name="name" type="text" />
|
1365
1356
|
```
|
1366
1357
|
|
1367
|
-
|
1358
|
+
#### email_field_tag
|
1368
1359
|
|
1369
|
-
|
1360
|
+
Creates a standard input field of email type.
|
1361
|
+
|
1362
|
+
```ruby
|
1363
|
+
email_field_tag 'email'
|
1364
|
+
# => <input id="email" name="email" type="email" />
|
1365
|
+
```
|
1370
1366
|
|
1371
|
-
####
|
1367
|
+
#### url_field_tag
|
1372
1368
|
|
1373
|
-
|
1369
|
+
Creates a standard input field of url type.
|
1374
1370
|
|
1375
1371
|
```ruby
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1372
|
+
url_field_tag 'url'
|
1373
|
+
# => <input id="url" name="url" type="url" />
|
1374
|
+
```
|
1375
|
+
|
1376
|
+
#### date_field_tag
|
1377
|
+
|
1378
|
+
Creates a standard input field of date type.
|
1379
|
+
|
1380
|
+
```ruby
|
1381
|
+
date_field_tag "dob"
|
1382
|
+
# => <input id="dob" name="dob" type="date" />
|
1381
1383
|
```
|
1382
1384
|
|
1383
|
-
|
1385
|
+
### JavaScriptHelper
|
1384
1386
|
|
1385
|
-
|
1387
|
+
Provides functionality for working with JavaScript in your views.
|
1386
1388
|
|
1387
1389
|
#### escape_javascript
|
1388
1390
|
|
@@ -1404,15 +1406,6 @@ alert('All is good')
|
|
1404
1406
|
</script>
|
1405
1407
|
```
|
1406
1408
|
|
1407
|
-
#### link_to_function
|
1408
|
-
|
1409
|
-
Returns a link that will trigger a JavaScript function using the onclick handler and return false after the fact.
|
1410
|
-
|
1411
|
-
```ruby
|
1412
|
-
link_to_function "Greeting", "alert('Hello world!')"
|
1413
|
-
# => <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
|
1414
|
-
```
|
1415
|
-
|
1416
1409
|
### NumberHelper
|
1417
1410
|
|
1418
1411
|
Provides methods for converting numbers into formatted strings. Methods are provided for phone numbers, currency, percentage, precision, positional notation, and file size.
|
@@ -1439,7 +1432,7 @@ number_to_human_size(1234567) # => 1.2 MB
|
|
1439
1432
|
Formats a number as a percentage string.
|
1440
1433
|
|
1441
1434
|
```ruby
|
1442
|
-
number_to_percentage(100, :
|
1435
|
+
number_to_percentage(100, precision: 0) # => 100%
|
1443
1436
|
```
|
1444
1437
|
|
1445
1438
|
#### number_to_phone
|
@@ -1467,94 +1460,102 @@ number_with_precision(111.2345) # => 111.235
|
|
1467
1460
|
number_with_precision(111.2345, 2) # => 111.23
|
1468
1461
|
```
|
1469
1462
|
|
1470
|
-
|
1471
|
-
---------------
|
1463
|
+
### SanitizeHelper
|
1472
1464
|
|
1473
|
-
|
1465
|
+
The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
|
1474
1466
|
|
1475
|
-
|
1467
|
+
#### sanitize
|
1476
1468
|
|
1477
|
-
|
1469
|
+
This sanitize helper will HTML encode all tags and strip all attributes that aren't specifically allowed.
|
1478
1470
|
|
1479
|
-
|
1471
|
+
```ruby
|
1472
|
+
sanitize @article.body
|
1473
|
+
```
|
1474
|
+
|
1475
|
+
If either the :attributes or :tags options are passed, only the mentioned tags and attributes are allowed and nothing else.
|
1480
1476
|
|
1481
1477
|
```ruby
|
1482
|
-
|
1478
|
+
sanitize @article.body, tags: %w(table tr td), attributes: %w(id class style)
|
1479
|
+
```
|
1483
1480
|
|
1484
|
-
|
1485
|
-
|
1481
|
+
To change defaults for multiple uses, for example adding table tags to the default:
|
1482
|
+
|
1483
|
+
```ruby
|
1484
|
+
class Application < Rails::Application
|
1485
|
+
config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
|
1486
1486
|
end
|
1487
1487
|
```
|
1488
1488
|
|
1489
|
-
|
1489
|
+
#### sanitize_css(style)
|
1490
1490
|
|
1491
|
-
|
1491
|
+
Sanitizes a block of CSS code.
|
1492
1492
|
|
1493
|
-
|
1494
|
-
|
1493
|
+
#### strip_links(html)
|
1494
|
+
Strips all link tags from text leaving just the link text.
|
1495
1495
|
|
1496
|
-
|
1496
|
+
```ruby
|
1497
|
+
strip_links("<a href="http://rubyonrails.org">Ruby on Rails</a>")
|
1498
|
+
# => Ruby on Rails
|
1499
|
+
```
|
1497
1500
|
|
1498
|
-
|
1501
|
+
```ruby
|
1502
|
+
strip_links("emails to <a href="mailto:me@email.com">me@email.com</a>.")
|
1503
|
+
# => emails to me@email.com.
|
1504
|
+
```
|
1499
1505
|
|
1500
|
-
```
|
1501
|
-
|
1502
|
-
|
1506
|
+
```ruby
|
1507
|
+
strip_links('Blog: <a href="http://myblog.com/">Visit</a>.')
|
1508
|
+
# => Blog: Visit.
|
1503
1509
|
```
|
1504
1510
|
|
1505
|
-
|
1511
|
+
#### strip_tags(html)
|
1506
1512
|
|
1507
|
-
|
1513
|
+
Strips all HTML tags from the html, including comments.
|
1514
|
+
This uses the html-scanner tokenizer and so its HTML parsing ability is limited by that of html-scanner.
|
1508
1515
|
|
1509
1516
|
```ruby
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
def hello_world(env)
|
1514
|
-
[200, {"Content-Type" => "text/html"}, "hello world".titleize]
|
1515
|
-
end
|
1517
|
+
strip_tags("Strip <i>these</i> tags!")
|
1518
|
+
# => Strip these tags!
|
1519
|
+
```
|
1516
1520
|
|
1517
|
-
|
1521
|
+
```ruby
|
1522
|
+
strip_tags("<b>Bold</b> no more! <a href='more.html'>See more</a>")
|
1523
|
+
# => Bold no more! See more
|
1518
1524
|
```
|
1519
1525
|
|
1520
|
-
|
1526
|
+
NB: The output may still contain unescaped '<', '>', '&' characters and confuse browsers.
|
1521
1527
|
|
1522
|
-
|
1523
|
-
$ ruby hello_world.rb
|
1524
|
-
```
|
1528
|
+
### CsrfHelper
|
1525
1529
|
|
1526
|
-
|
1530
|
+
Returns meta tags "csrf-param" and "csrf-token" with the name of the cross-site
|
1531
|
+
request forgery protection parameter and token, respectively.
|
1527
1532
|
|
1528
|
-
|
1533
|
+
```html
|
1534
|
+
<%= csrf_meta_tags %>
|
1535
|
+
```
|
1529
1536
|
|
1530
|
-
|
1537
|
+
NOTE: Regular forms generate hidden fields so they do not use these tags. More
|
1538
|
+
details can be found in the [Rails Security Guide](security.html#cross-site-request-forgery-csrf).
|
1531
1539
|
|
1532
|
-
|
1540
|
+
Localized Views
|
1541
|
+
---------------
|
1533
1542
|
|
1534
|
-
|
1535
|
-
$ gem install actionpack
|
1536
|
-
$ gem install sinatra
|
1537
|
-
```
|
1543
|
+
Action View has the ability render different templates depending on the current locale.
|
1538
1544
|
|
1539
|
-
|
1545
|
+
For example, suppose you have a `ArticlesController` with a show action. By default, calling this action will render `app/views/articles/show.html.erb`. But if you set `I18n.locale = :de`, then `app/views/articles/show.de.html.erb` will be rendered instead. If the localized template isn't present, the undecorated version will be used. This means you're not required to provide localized views for all cases, but they will be preferred and used if available.
|
1540
1546
|
|
1541
|
-
|
1547
|
+
You can use the same technique to localize the rescue files in your public directory. For example, setting `I18n.locale = :de` and creating `public/500.de.html` and `public/404.de.html` would allow you to have localized rescue pages.
|
1548
|
+
|
1549
|
+
Since Rails doesn't restrict the symbols that you use to set I18n.locale, you can leverage this system to display different content depending on anything you like. For example, suppose you have some "expert" users that should see different pages from "normal" users. You could add the following to `app/controllers/application.rb`:
|
1542
1550
|
|
1543
1551
|
```ruby
|
1544
|
-
|
1545
|
-
require 'sinatra'
|
1552
|
+
before_action :set_expert_locale
|
1546
1553
|
|
1547
|
-
|
1548
|
-
|
1554
|
+
def set_expert_locale
|
1555
|
+
I18n.locale = :expert if current_user.expert?
|
1549
1556
|
end
|
1550
1557
|
```
|
1551
1558
|
|
1552
|
-
Then
|
1559
|
+
Then you could create special views like `app/views/articles/show.expert.html.erb` that would only be displayed to expert users.
|
1553
1560
|
|
1554
|
-
|
1555
|
-
$ ruby hello_world.rb
|
1556
|
-
```
|
1557
|
-
|
1558
|
-
Once the application is running, you can see Sinatra and Action View working together by visiting `http://localhost:4567/`
|
1559
|
-
|
1560
|
-
TODO needs a screenshot? I have one - not sure where to put it.
|
1561
|
+
You can read more about the Rails Internationalization (I18n) API [here](i18n.html).
|