rails 4.1.6 → 4.2.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +12 -10
- data/guides/CHANGELOG.md +64 -17
- data/guides/Rakefile +21 -6
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/assets/javascripts/guides.js +6 -0
- data/guides/assets/stylesheets/main.css +4 -1
- data/guides/bug_report_templates/action_controller_gem.rb +3 -3
- data/guides/bug_report_templates/action_controller_master.rb +3 -2
- data/guides/bug_report_templates/active_record_gem.rb +1 -1
- data/guides/bug_report_templates/generic_gem.rb +15 -0
- data/guides/bug_report_templates/generic_master.rb +26 -0
- data/guides/rails_guides/helpers.rb +1 -1
- data/guides/rails_guides/levenshtein.rb +27 -21
- data/guides/rails_guides/markdown/renderer.rb +1 -1
- data/guides/rails_guides/markdown.rb +11 -7
- data/guides/rails_guides.rb +2 -2
- data/guides/source/2_2_release_notes.md +1 -1
- data/guides/source/2_3_release_notes.md +4 -4
- data/guides/source/3_0_release_notes.md +8 -8
- data/guides/source/3_1_release_notes.md +6 -3
- data/guides/source/3_2_release_notes.md +6 -3
- data/guides/source/4_0_release_notes.md +6 -3
- data/guides/source/4_1_release_notes.md +9 -10
- 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 -8
- data/guides/source/action_controller_overview.md +25 -8
- data/guides/source/action_mailer_basics.md +97 -29
- data/guides/source/action_view_overview.md +142 -191
- data/guides/source/active_job_basics.md +339 -0
- data/guides/source/active_model_basics.md +371 -17
- data/guides/source/active_record_basics.md +25 -24
- data/guides/source/active_record_callbacks.md +12 -9
- data/guides/source/{migrations.md → active_record_migrations.md} +95 -220
- data/guides/source/active_record_postgresql.md +433 -0
- data/guides/source/active_record_querying.md +264 -268
- data/guides/source/active_record_validations.md +23 -13
- data/guides/source/active_support_core_extensions.md +115 -123
- data/guides/source/active_support_instrumentation.md +10 -18
- data/guides/source/api_documentation_guidelines.md +63 -17
- data/guides/source/asset_pipeline.md +259 -120
- data/guides/source/association_basics.md +96 -80
- data/guides/source/autoloading_and_reloading_constants.md +1311 -0
- data/guides/source/caching_with_rails.md +32 -7
- data/guides/source/command_line.md +52 -30
- data/guides/source/configuring.md +161 -33
- data/guides/source/contributing_to_ruby_on_rails.md +198 -114
- data/guides/source/credits.html.erb +2 -2
- data/guides/source/debugging_rails_applications.md +440 -286
- data/guides/source/development_dependencies_install.md +47 -36
- data/guides/source/documents.yaml +19 -7
- data/guides/source/engines.md +217 -196
- data/guides/source/form_helpers.md +79 -56
- data/guides/source/generators.md +24 -11
- data/guides/source/getting_started.md +359 -219
- data/guides/source/i18n.md +110 -66
- data/guides/source/index.html.erb +1 -0
- data/guides/source/initialization.md +109 -62
- data/guides/source/layout.html.erb +5 -11
- data/guides/source/layouts_and_rendering.md +26 -26
- data/guides/source/maintenance_policy.md +6 -3
- data/guides/source/nested_model_forms.md +7 -4
- data/guides/source/plugins.md +27 -27
- data/guides/source/rails_application_templates.md +21 -3
- data/guides/source/rails_on_rack.md +8 -5
- data/guides/source/routing.md +113 -73
- data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
- data/guides/source/security.md +40 -34
- data/guides/source/testing.md +199 -119
- data/guides/source/upgrading_ruby_on_rails.md +289 -31
- data/guides/source/working_with_javascript_in_rails.md +19 -17
- data/guides/w3c_validator.rb +2 -0
- metadata +42 -95
- data/guides/code/getting_started/Gemfile +0 -40
- data/guides/code/getting_started/Gemfile.lock +0 -125
- 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 -15
- 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 -23
- data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -53
- 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 -4
- 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/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/config.ru +0 -4
- 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 -60
- data/guides/code/getting_started/public/422.html +0 -60
- data/guides/code/getting_started/public/500.html +0 -59
- 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 -12
data/guides/source/engines.md
CHANGED
@@ -31,27 +31,28 @@ Engines are also closely related to plugins. The two share a common `lib`
|
|
31
31
|
directory structure, and are both generated using the `rails plugin new`
|
32
32
|
generator. The difference is that an engine is considered a "full plugin" by
|
33
33
|
Rails (as indicated by the `--full` option that's passed to the generator
|
34
|
-
command).
|
35
|
-
|
34
|
+
command). We'll actually be using the `--mountable` option here, which includes
|
35
|
+
all the features of `--full`, and then some. This guide will refer to these
|
36
|
+
"full plugins" simply as "engines" throughout. An engine **can** be a plugin,
|
37
|
+
and a plugin **can** be an engine.
|
36
38
|
|
37
|
-
The engine that will be created in this guide will be called "blorgh".
|
39
|
+
The engine that will be created in this guide will be called "blorgh". This
|
38
40
|
engine will provide blogging functionality to its host applications, allowing
|
39
|
-
for new
|
41
|
+
for new articles and comments to be created. At the beginning of this guide, you
|
40
42
|
will be working solely within the engine itself, but in later sections you'll
|
41
43
|
see how to hook it into an application.
|
42
44
|
|
43
45
|
Engines can also be isolated from their host applications. This means that an
|
44
46
|
application is able to have a path provided by a routing helper such as
|
45
|
-
`
|
46
|
-
`
|
47
|
+
`articles_path` and use an engine also that provides a path also called
|
48
|
+
`articles_path`, and the two would not clash. Along with this, controllers, models
|
47
49
|
and table names are also namespaced. You'll see how to do this later in this
|
48
50
|
guide.
|
49
51
|
|
50
52
|
It's important to keep in mind at all times that the application should
|
51
53
|
**always** take precedence over its engines. An application is the object that
|
52
|
-
has final say in what goes on in
|
53
|
-
|
54
|
-
than changing it drastically.
|
54
|
+
has final say in what goes on in its environment. The engine should
|
55
|
+
only be enhancing it, rather than changing it drastically.
|
55
56
|
|
56
57
|
To see demonstrations of other engines, check out
|
57
58
|
[Devise](https://github.com/plataformatec/devise), an engine that provides
|
@@ -73,17 +74,20 @@ options as appropriate to the need. For the "blorgh" example, you will need to
|
|
73
74
|
create a "mountable" engine, running this command in a terminal:
|
74
75
|
|
75
76
|
```bash
|
76
|
-
$
|
77
|
+
$ rails plugin new blorgh --mountable
|
77
78
|
```
|
78
79
|
|
79
80
|
The full list of options for the plugin generator may be seen by typing:
|
80
81
|
|
81
82
|
```bash
|
82
|
-
$
|
83
|
+
$ rails plugin --help
|
83
84
|
```
|
84
85
|
|
85
|
-
The `--
|
86
|
-
|
86
|
+
The `--mountable` option tells the generator that you want to create a
|
87
|
+
"mountable" and namespace-isolated engine. This generator will provide the same
|
88
|
+
skeleton structure as would the `--full` option. The `--full` option tells the
|
89
|
+
generator that you want to create an engine, including a skeleton structure
|
90
|
+
that provides the following:
|
87
91
|
|
88
92
|
* An `app` directory tree
|
89
93
|
* A `config/routes.rb` file:
|
@@ -94,7 +98,7 @@ including a skeleton structure that provides the following:
|
|
94
98
|
```
|
95
99
|
|
96
100
|
* A file at `lib/blorgh/engine.rb`, which is identical in function to a
|
97
|
-
|
101
|
+
standard Rails application's `config/application.rb` file:
|
98
102
|
|
99
103
|
```ruby
|
100
104
|
module Blorgh
|
@@ -103,9 +107,7 @@ including a skeleton structure that provides the following:
|
|
103
107
|
end
|
104
108
|
```
|
105
109
|
|
106
|
-
The `--mountable` option
|
107
|
-
"mountable" and namespace-isolated engine. This generator will provide the same
|
108
|
-
skeleton structure as would the `--full` option, and will add:
|
110
|
+
The `--mountable` option will add to the `--full` option:
|
109
111
|
|
110
112
|
* Asset manifest files (`application.js` and `application.css`)
|
111
113
|
* A namespaced `ApplicationController` stub
|
@@ -134,7 +136,7 @@ following to the dummy application's routes file at
|
|
134
136
|
`test/dummy/config/routes.rb`:
|
135
137
|
|
136
138
|
```ruby
|
137
|
-
mount Blorgh::Engine
|
139
|
+
mount Blorgh::Engine => "/blorgh"
|
138
140
|
```
|
139
141
|
|
140
142
|
### Inside an Engine
|
@@ -171,7 +173,7 @@ Within `lib/blorgh/engine.rb` is the base class for the engine:
|
|
171
173
|
|
172
174
|
```ruby
|
173
175
|
module Blorgh
|
174
|
-
class Engine < Rails::Engine
|
176
|
+
class Engine < ::Rails::Engine
|
175
177
|
isolate_namespace Blorgh
|
176
178
|
end
|
177
179
|
end
|
@@ -197,12 +199,12 @@ within the `Engine` class definition. Without it, classes generated in an engine
|
|
197
199
|
**may** conflict with an application.
|
198
200
|
|
199
201
|
What this isolation of the namespace means is that a model generated by a call
|
200
|
-
to `bin/rails g model`, such as `bin/rails g model
|
201
|
-
instead be namespaced and called `Blorgh::
|
202
|
-
model is namespaced, becoming `
|
203
|
-
Similar to the model namespacing, a controller called `
|
204
|
-
`Blorgh::
|
205
|
-
`app/views/
|
202
|
+
to `bin/rails g model`, such as `bin/rails g model article`, won't be called `Article`, but
|
203
|
+
instead be namespaced and called `Blorgh::Article`. In addition, the table for the
|
204
|
+
model is namespaced, becoming `blorgh_articles`, rather than simply `articles`.
|
205
|
+
Similar to the model namespacing, a controller called `ArticlesController` becomes
|
206
|
+
`Blorgh::ArticlesController` and the views for that controller will not be at
|
207
|
+
`app/views/articles`, but `app/views/blorgh/articles` instead. Mailers are namespaced
|
206
208
|
as well.
|
207
209
|
|
208
210
|
Finally, routes will also be isolated within the engine. This is one of the most
|
@@ -283,74 +285,72 @@ created in the `test` directory as well. For example, you may wish to create a
|
|
283
285
|
Providing engine functionality
|
284
286
|
------------------------------
|
285
287
|
|
286
|
-
The engine that this guide covers provides
|
287
|
-
and follows a similar thread to the [Getting Started
|
288
|
+
The engine that this guide covers provides submitting articles and commenting
|
289
|
+
functionality and follows a similar thread to the [Getting Started
|
288
290
|
Guide](getting_started.html), with some new twists.
|
289
291
|
|
290
|
-
### Generating
|
292
|
+
### Generating an Article Resource
|
291
293
|
|
292
|
-
The first thing to generate for a blog engine is the `
|
294
|
+
The first thing to generate for a blog engine is the `Article` model and related
|
293
295
|
controller. To quickly generate this, you can use the Rails scaffold generator.
|
294
296
|
|
295
297
|
```bash
|
296
|
-
$ bin/rails generate scaffold
|
298
|
+
$ bin/rails generate scaffold article title:string text:text
|
297
299
|
```
|
298
300
|
|
299
301
|
This command will output this information:
|
300
302
|
|
301
303
|
```
|
302
304
|
invoke active_record
|
303
|
-
create db/migrate/[timestamp]
|
304
|
-
create app/models/blorgh/
|
305
|
+
create db/migrate/[timestamp]_create_blorgh_articles.rb
|
306
|
+
create app/models/blorgh/article.rb
|
305
307
|
invoke test_unit
|
306
|
-
create test/models/blorgh/
|
307
|
-
create test/fixtures/blorgh/
|
308
|
+
create test/models/blorgh/article_test.rb
|
309
|
+
create test/fixtures/blorgh/articles.yml
|
308
310
|
invoke resource_route
|
309
|
-
route resources :
|
311
|
+
route resources :articles
|
310
312
|
invoke scaffold_controller
|
311
|
-
create app/controllers/blorgh/
|
313
|
+
create app/controllers/blorgh/articles_controller.rb
|
312
314
|
invoke erb
|
313
|
-
create app/views/blorgh/
|
314
|
-
create app/views/blorgh/
|
315
|
-
create app/views/blorgh/
|
316
|
-
create app/views/blorgh/
|
317
|
-
create app/views/blorgh/
|
318
|
-
create app/views/blorgh/
|
315
|
+
create app/views/blorgh/articles
|
316
|
+
create app/views/blorgh/articles/index.html.erb
|
317
|
+
create app/views/blorgh/articles/edit.html.erb
|
318
|
+
create app/views/blorgh/articles/show.html.erb
|
319
|
+
create app/views/blorgh/articles/new.html.erb
|
320
|
+
create app/views/blorgh/articles/_form.html.erb
|
319
321
|
invoke test_unit
|
320
|
-
create test/controllers/blorgh/
|
322
|
+
create test/controllers/blorgh/articles_controller_test.rb
|
321
323
|
invoke helper
|
322
|
-
create app/helpers/blorgh/
|
323
|
-
invoke test_unit
|
324
|
-
create test/helpers/blorgh/posts_helper_test.rb
|
324
|
+
create app/helpers/blorgh/articles_helper.rb
|
325
325
|
invoke assets
|
326
326
|
invoke js
|
327
|
-
create app/assets/javascripts/blorgh/
|
327
|
+
create app/assets/javascripts/blorgh/articles.js
|
328
328
|
invoke css
|
329
|
-
create app/assets/stylesheets/blorgh/
|
329
|
+
create app/assets/stylesheets/blorgh/articles.css
|
330
330
|
invoke css
|
331
331
|
create app/assets/stylesheets/scaffold.css
|
332
332
|
```
|
333
333
|
|
334
334
|
The first thing that the scaffold generator does is invoke the `active_record`
|
335
335
|
generator, which generates a migration and a model for the resource. Note here,
|
336
|
-
however, that the migration is called `
|
337
|
-
usual `
|
336
|
+
however, that the migration is called `create_blorgh_articles` rather than the
|
337
|
+
usual `create_articles`. This is due to the `isolate_namespace` method called in
|
338
338
|
the `Blorgh::Engine` class's definition. The model here is also namespaced,
|
339
|
-
being placed at `app/models/blorgh/
|
339
|
+
being placed at `app/models/blorgh/article.rb` rather than `app/models/article.rb` due
|
340
340
|
to the `isolate_namespace` call within the `Engine` class.
|
341
341
|
|
342
342
|
Next, the `test_unit` generator is invoked for this model, generating a model
|
343
|
-
test at `test/models/blorgh/
|
344
|
-
`test/models/
|
345
|
-
(rather than `test/fixtures/
|
343
|
+
test at `test/models/blorgh/article_test.rb` (rather than
|
344
|
+
`test/models/article_test.rb`) and a fixture at `test/fixtures/blorgh/articles.yml`
|
345
|
+
(rather than `test/fixtures/articles.yml`).
|
346
346
|
|
347
347
|
After that, a line for the resource is inserted into the `config/routes.rb` file
|
348
|
-
for the engine. This line is simply `resources :
|
348
|
+
for the engine. This line is simply `resources :articles`, turning the
|
349
349
|
`config/routes.rb` file for the engine into this:
|
350
350
|
|
351
351
|
```ruby
|
352
352
|
Blorgh::Engine.routes.draw do
|
353
|
-
resources :
|
353
|
+
resources :articles
|
354
354
|
end
|
355
355
|
```
|
356
356
|
|
@@ -362,18 +362,18 @@ be isolated from those routes that are within the application. The
|
|
362
362
|
[Routes](#routes) section of this guide describes it in detail.
|
363
363
|
|
364
364
|
Next, the `scaffold_controller` generator is invoked, generating a controller
|
365
|
-
called `Blorgh::
|
366
|
-
`app/controllers/blorgh/
|
367
|
-
`app/views/blorgh/
|
368
|
-
controller (`test/controllers/blorgh/
|
369
|
-
(`app/helpers/blorgh/
|
365
|
+
called `Blorgh::ArticlesController` (at
|
366
|
+
`app/controllers/blorgh/articles_controller.rb`) and its related views at
|
367
|
+
`app/views/blorgh/articles`. This generator also generates a test for the
|
368
|
+
controller (`test/controllers/blorgh/articles_controller_test.rb`) and a helper
|
369
|
+
(`app/helpers/blorgh/articles_controller.rb`).
|
370
370
|
|
371
371
|
Everything this generator has created is neatly namespaced. The controller's
|
372
372
|
class is defined within the `Blorgh` module:
|
373
373
|
|
374
374
|
```ruby
|
375
375
|
module Blorgh
|
376
|
-
class
|
376
|
+
class ArticlesController < ApplicationController
|
377
377
|
...
|
378
378
|
end
|
379
379
|
end
|
@@ -382,22 +382,22 @@ end
|
|
382
382
|
NOTE: The `ApplicationController` class being inherited from here is the
|
383
383
|
`Blorgh::ApplicationController`, not an application's `ApplicationController`.
|
384
384
|
|
385
|
-
The helper inside `app/helpers/blorgh/
|
385
|
+
The helper inside `app/helpers/blorgh/articles_helper.rb` is also namespaced:
|
386
386
|
|
387
387
|
```ruby
|
388
388
|
module Blorgh
|
389
|
-
module
|
389
|
+
module ArticlesHelper
|
390
390
|
...
|
391
391
|
end
|
392
392
|
end
|
393
393
|
```
|
394
394
|
|
395
395
|
This helps prevent conflicts with any other engine or application that may have
|
396
|
-
|
396
|
+
an article resource as well.
|
397
397
|
|
398
398
|
Finally, the assets for this resource are generated in two files:
|
399
|
-
`app/assets/javascripts/blorgh/
|
400
|
-
`app/assets/stylesheets/blorgh/
|
399
|
+
`app/assets/javascripts/blorgh/articles.js` and
|
400
|
+
`app/assets/stylesheets/blorgh/articles.css`. You'll see how to use these a little
|
401
401
|
later.
|
402
402
|
|
403
403
|
By default, the scaffold styling is not applied to the engine because the
|
@@ -412,46 +412,46 @@ tag of this layout:
|
|
412
412
|
You can see what the engine has so far by running `rake db:migrate` at the root
|
413
413
|
of our engine to run the migration generated by the scaffold generator, and then
|
414
414
|
running `rails server` in `test/dummy`. When you open
|
415
|
-
`http://localhost:3000/blorgh/
|
415
|
+
`http://localhost:3000/blorgh/articles` you will see the default scaffold that has
|
416
416
|
been generated. Click around! You've just generated your first engine's first
|
417
417
|
functions.
|
418
418
|
|
419
419
|
If you'd rather play around in the console, `rails console` will also work just
|
420
|
-
like a Rails application. Remember: the `
|
421
|
-
reference it you must call it as `Blorgh::
|
420
|
+
like a Rails application. Remember: the `Article` model is namespaced, so to
|
421
|
+
reference it you must call it as `Blorgh::Article`.
|
422
422
|
|
423
423
|
```ruby
|
424
|
-
>> Blorgh::
|
425
|
-
=> #<Blorgh::
|
424
|
+
>> Blorgh::Article.find(1)
|
425
|
+
=> #<Blorgh::Article id: 1 ...>
|
426
426
|
```
|
427
427
|
|
428
|
-
One final thing is that the `
|
428
|
+
One final thing is that the `articles` resource for this engine should be the root
|
429
429
|
of the engine. Whenever someone goes to the root path where the engine is
|
430
|
-
mounted, they should be shown a list of
|
430
|
+
mounted, they should be shown a list of articles. This can be made to happen if
|
431
431
|
this line is inserted into the `config/routes.rb` file inside the engine:
|
432
432
|
|
433
433
|
```ruby
|
434
|
-
root to: "
|
434
|
+
root to: "articles#index"
|
435
435
|
```
|
436
436
|
|
437
|
-
Now people will only need to go to the root of the engine to see all the
|
438
|
-
rather than visiting `/
|
439
|
-
`http://localhost:3000/blorgh/
|
437
|
+
Now people will only need to go to the root of the engine to see all the articles,
|
438
|
+
rather than visiting `/articles`. This means that instead of
|
439
|
+
`http://localhost:3000/blorgh/articles`, you only need to go to
|
440
440
|
`http://localhost:3000/blorgh` now.
|
441
441
|
|
442
442
|
### Generating a Comments Resource
|
443
443
|
|
444
|
-
Now that the engine can create new
|
444
|
+
Now that the engine can create new articles, it only makes sense to add
|
445
445
|
commenting functionality as well. To do this, you'll need to generate a comment
|
446
|
-
model, a comment controller and then modify the
|
446
|
+
model, a comment controller and then modify the articles scaffold to display
|
447
447
|
comments and allow people to create new ones.
|
448
448
|
|
449
449
|
From the application root, run the model generator. Tell it to generate a
|
450
|
-
`Comment` model, with the related table having two columns: a `
|
450
|
+
`Comment` model, with the related table having two columns: a `article_id` integer
|
451
451
|
and `text` text column.
|
452
452
|
|
453
453
|
```bash
|
454
|
-
$ bin/rails generate model Comment
|
454
|
+
$ bin/rails generate model Comment article_id:integer text:text
|
455
455
|
```
|
456
456
|
|
457
457
|
This will output the following:
|
@@ -471,20 +471,20 @@ called `Blorgh::Comment`. Now run the migration to create our blorgh_comments
|
|
471
471
|
table:
|
472
472
|
|
473
473
|
```bash
|
474
|
-
$
|
474
|
+
$ rake db:migrate
|
475
475
|
```
|
476
476
|
|
477
|
-
To show the comments on
|
477
|
+
To show the comments on an article, edit `app/views/blorgh/articles/show.html.erb` and
|
478
478
|
add this line before the "Edit" link:
|
479
479
|
|
480
480
|
```html+erb
|
481
481
|
<h3>Comments</h3>
|
482
|
-
<%= render @
|
482
|
+
<%= render @article.comments %>
|
483
483
|
```
|
484
484
|
|
485
485
|
This line will require there to be a `has_many` association for comments defined
|
486
|
-
on the `Blorgh::
|
487
|
-
`app/models/blorgh/
|
486
|
+
on the `Blorgh::Article` model, which there isn't right now. To define one, open
|
487
|
+
`app/models/blorgh/article.rb` and add this line into the model:
|
488
488
|
|
489
489
|
```ruby
|
490
490
|
has_many :comments
|
@@ -494,7 +494,7 @@ Turning the model into this:
|
|
494
494
|
|
495
495
|
```ruby
|
496
496
|
module Blorgh
|
497
|
-
class
|
497
|
+
class Article < ActiveRecord::Base
|
498
498
|
has_many :comments
|
499
499
|
end
|
500
500
|
end
|
@@ -505,9 +505,9 @@ NOTE: Because the `has_many` is defined inside a class that is inside the
|
|
505
505
|
model for these objects, so there's no need to specify that using the
|
506
506
|
`:class_name` option here.
|
507
507
|
|
508
|
-
Next, there needs to be a form so that comments can be created on
|
509
|
-
this, put this line underneath the call to `render @
|
510
|
-
`app/views/blorgh/
|
508
|
+
Next, there needs to be a form so that comments can be created on an article. To
|
509
|
+
add this, put this line underneath the call to `render @article.comments` in
|
510
|
+
`app/views/blorgh/articles/show.html.erb`:
|
511
511
|
|
512
512
|
```erb
|
513
513
|
<%= render "blorgh/comments/form" %>
|
@@ -519,7 +519,7 @@ directory at `app/views/blorgh/comments` and in it a new file called
|
|
519
519
|
|
520
520
|
```html+erb
|
521
521
|
<h3>New comment</h3>
|
522
|
-
<%= form_for [@
|
522
|
+
<%= form_for [@article, @article.comments.build] do |f| %>
|
523
523
|
<p>
|
524
524
|
<%= f.label :text %><br>
|
525
525
|
<%= f.text_area :text %>
|
@@ -529,12 +529,12 @@ directory at `app/views/blorgh/comments` and in it a new file called
|
|
529
529
|
```
|
530
530
|
|
531
531
|
When this form is submitted, it is going to attempt to perform a `POST` request
|
532
|
-
to a route of `/
|
533
|
-
exist at the moment, but can be created by changing the `resources :
|
532
|
+
to a route of `/articles/:article_id/comments` within the engine. This route doesn't
|
533
|
+
exist at the moment, but can be created by changing the `resources :articles` line
|
534
534
|
inside `config/routes.rb` into these lines:
|
535
535
|
|
536
536
|
```ruby
|
537
|
-
resources :
|
537
|
+
resources :articles do
|
538
538
|
resources :comments
|
539
539
|
end
|
540
540
|
```
|
@@ -558,8 +558,6 @@ invoke test_unit
|
|
558
558
|
create test/controllers/blorgh/comments_controller_test.rb
|
559
559
|
invoke helper
|
560
560
|
create app/helpers/blorgh/comments_helper.rb
|
561
|
-
invoke test_unit
|
562
|
-
create test/helpers/blorgh/comments_helper_test.rb
|
563
561
|
invoke assets
|
564
562
|
invoke js
|
565
563
|
create app/assets/javascripts/blorgh/comments.js
|
@@ -567,17 +565,17 @@ invoke css
|
|
567
565
|
create app/assets/stylesheets/blorgh/comments.css
|
568
566
|
```
|
569
567
|
|
570
|
-
The form will be making a `POST` request to `/
|
568
|
+
The form will be making a `POST` request to `/articles/:article_id/comments`, which
|
571
569
|
will correspond with the `create` action in `Blorgh::CommentsController`. This
|
572
570
|
action needs to be created, which can be done by putting the following lines
|
573
571
|
inside the class definition in `app/controllers/blorgh/comments_controller.rb`:
|
574
572
|
|
575
573
|
```ruby
|
576
574
|
def create
|
577
|
-
@
|
578
|
-
@comment = @
|
575
|
+
@article = Article.find(params[:article_id])
|
576
|
+
@comment = @article.comments.create(comment_params)
|
579
577
|
flash[:notice] = "Comment has been created!"
|
580
|
-
redirect_to
|
578
|
+
redirect_to articles_path
|
581
579
|
end
|
582
580
|
|
583
581
|
private
|
@@ -590,17 +588,17 @@ This is the final step required to get the new comment form working. Displaying
|
|
590
588
|
the comments, however, is not quite right yet. If you were to create a comment
|
591
589
|
right now, you would see this error:
|
592
590
|
|
593
|
-
```
|
594
|
-
Missing partial blorgh/comments/
|
591
|
+
```
|
592
|
+
Missing partial blorgh/comments/_comment with {:handlers=>[:erb, :builder],
|
595
593
|
:formats=>[:html], :locale=>[:en, :en]}. Searched in: *
|
596
594
|
"/Users/ryan/Sites/side_projects/blorgh/test/dummy/app/views" *
|
597
|
-
"/Users/ryan/Sites/side_projects/blorgh/app/views"
|
595
|
+
"/Users/ryan/Sites/side_projects/blorgh/app/views"
|
598
596
|
```
|
599
597
|
|
600
598
|
The engine is unable to find the partial required for rendering the comments.
|
601
599
|
Rails looks first in the application's (`test/dummy`) `app/views` directory and
|
602
600
|
then in the engine's `app/views` directory. When it can't find it, it will throw
|
603
|
-
this error. The engine knows to look for `blorgh/comments/
|
601
|
+
this error. The engine knows to look for `blorgh/comments/_comment` because the
|
604
602
|
model object it is receiving is from the `Blorgh::Comment` class.
|
605
603
|
|
606
604
|
This partial will be responsible for rendering just the comment text, for now.
|
@@ -612,7 +610,7 @@ line inside it:
|
|
612
610
|
```
|
613
611
|
|
614
612
|
The `comment_counter` local variable is given to us by the `<%= render
|
615
|
-
@
|
613
|
+
@article.comments %>` call, which will define it automatically and increment the
|
616
614
|
counter as it iterates through each comment. It's used in this example to
|
617
615
|
display a small number next to each comment when it's created.
|
618
616
|
|
@@ -625,7 +623,7 @@ Hooking Into an Application
|
|
625
623
|
Using an engine within an application is very easy. This section covers how to
|
626
624
|
mount the engine into an application and the initial setup required, as well as
|
627
625
|
linking the engine to a `User` class provided by the application to provide
|
628
|
-
ownership for
|
626
|
+
ownership for articles and comments within the engine.
|
629
627
|
|
630
628
|
### Mounting the Engine
|
631
629
|
|
@@ -676,20 +674,20 @@ pre-defined path which may be customizable.
|
|
676
674
|
|
677
675
|
### Engine setup
|
678
676
|
|
679
|
-
The engine contains migrations for the `
|
677
|
+
The engine contains migrations for the `blorgh_articles` and `blorgh_comments`
|
680
678
|
table which need to be created in the application's database so that the
|
681
679
|
engine's models can query them correctly. To copy these migrations into the
|
682
680
|
application use this command:
|
683
681
|
|
684
682
|
```bash
|
685
|
-
$
|
683
|
+
$ rake blorgh:install:migrations
|
686
684
|
```
|
687
685
|
|
688
686
|
If you have multiple engines that need migrations copied over, use
|
689
687
|
`railties:install:migrations` instead:
|
690
688
|
|
691
689
|
```bash
|
692
|
-
$
|
690
|
+
$ rake railties:install:migrations
|
693
691
|
```
|
694
692
|
|
695
693
|
This command, when run for the first time, will copy over all the migrations
|
@@ -698,8 +696,8 @@ haven't been copied over already. The first run for this command will output
|
|
698
696
|
something such as this:
|
699
697
|
|
700
698
|
```bash
|
701
|
-
Copied migration [timestamp_1]
|
702
|
-
Copied migration [timestamp_2]_create_blorgh_comments.rb from blorgh
|
699
|
+
Copied migration [timestamp_1]_create_blorgh_articles.blorgh.rb from blorgh
|
700
|
+
Copied migration [timestamp_2]_create_blorgh_comments.blorgh.rb from blorgh
|
703
701
|
```
|
704
702
|
|
705
703
|
The first timestamp (`[timestamp_1]`) will be the current time, and the second
|
@@ -709,7 +707,7 @@ migrations in the application.
|
|
709
707
|
|
710
708
|
To run these migrations within the context of the application, simply run `rake
|
711
709
|
db:migrate`. When accessing the engine through `http://localhost:3000/blog`, the
|
712
|
-
|
710
|
+
articles will be empty. This is because the table created inside the application is
|
713
711
|
different from the one created within the engine. Go ahead, play around with the
|
714
712
|
newly mounted engine. You'll find that it's the same as when it was only an
|
715
713
|
engine.
|
@@ -734,17 +732,19 @@ rake db:migrate SCOPE=blorgh VERSION=0
|
|
734
732
|
|
735
733
|
When an engine is created, it may want to use specific classes from an
|
736
734
|
application to provide links between the pieces of the engine and the pieces of
|
737
|
-
the application. In the case of the `blorgh` engine, making
|
735
|
+
the application. In the case of the `blorgh` engine, making articles and comments
|
738
736
|
have authors would make a lot of sense.
|
739
737
|
|
740
738
|
A typical application might have a `User` class that would be used to represent
|
741
|
-
authors for
|
742
|
-
calls this class something different, such as `Person`. For this
|
743
|
-
engine should not hardcode associations specifically for a `User`
|
739
|
+
authors for an article or a comment. But there could be a case where the
|
740
|
+
application calls this class something different, such as `Person`. For this
|
741
|
+
reason, the engine should not hardcode associations specifically for a `User`
|
742
|
+
class.
|
744
743
|
|
745
744
|
To keep it simple in this case, the application will have a class called `User`
|
746
|
-
that represents the users of the application
|
747
|
-
command inside the
|
745
|
+
that represents the users of the application (we'll get into making this
|
746
|
+
configurable further on). It can be generated using this command inside the
|
747
|
+
application:
|
748
748
|
|
749
749
|
```bash
|
750
750
|
rails g model user name:string
|
@@ -753,14 +753,14 @@ rails g model user name:string
|
|
753
753
|
The `rake db:migrate` command needs to be run here to ensure that our
|
754
754
|
application has the `users` table for future use.
|
755
755
|
|
756
|
-
Also, to keep it simple, the
|
756
|
+
Also, to keep it simple, the articles form will have a new text field called
|
757
757
|
`author_name`, where users can elect to put their name. The engine will then
|
758
758
|
take this name and either create a new `User` object from it, or find one that
|
759
|
-
already has that name. The engine will then associate the
|
759
|
+
already has that name. The engine will then associate the article with the found or
|
760
760
|
created `User` object.
|
761
761
|
|
762
762
|
First, the `author_name` text field needs to be added to the
|
763
|
-
`app/views/blorgh/
|
763
|
+
`app/views/blorgh/articles/_form.html.erb` partial inside the engine. This can be
|
764
764
|
added above the `title` field with this code:
|
765
765
|
|
766
766
|
```html+erb
|
@@ -770,23 +770,23 @@ added above the `title` field with this code:
|
|
770
770
|
</div>
|
771
771
|
```
|
772
772
|
|
773
|
-
Next, we need to update our `Blorgh::
|
773
|
+
Next, we need to update our `Blorgh::ArticleController#article_params` method to
|
774
774
|
permit the new form parameter:
|
775
775
|
|
776
776
|
```ruby
|
777
|
-
def
|
778
|
-
params.require(:
|
777
|
+
def article_params
|
778
|
+
params.require(:article).permit(:title, :text, :author_name)
|
779
779
|
end
|
780
780
|
```
|
781
781
|
|
782
|
-
The `Blorgh::
|
783
|
-
field into an actual `User` object and associate it as that
|
784
|
-
before the
|
782
|
+
The `Blorgh::Article` model should then have some code to convert the `author_name`
|
783
|
+
field into an actual `User` object and associate it as that article's `author`
|
784
|
+
before the article is saved. It will also need to have an `attr_accessor` set up
|
785
785
|
for this field, so that the setter and getter methods are defined for it.
|
786
786
|
|
787
787
|
To do all this, you'll need to add the `attr_accessor` for `author_name`, the
|
788
788
|
association for the author and the `before_save` call into
|
789
|
-
`app/models/blorgh/
|
789
|
+
`app/models/blorgh/article.rb`. The `author` association will be hard-coded to the
|
790
790
|
`User` class for the time being.
|
791
791
|
|
792
792
|
```ruby
|
@@ -803,14 +803,14 @@ private
|
|
803
803
|
|
804
804
|
By representing the `author` association's object with the `User` class, a link
|
805
805
|
is established between the engine and the application. There needs to be a way
|
806
|
-
of associating the records in the `
|
806
|
+
of associating the records in the `blorgh_articles` table with the records in the
|
807
807
|
`users` table. Because the association is called `author`, there should be an
|
808
|
-
`author_id` column added to the `
|
808
|
+
`author_id` column added to the `blorgh_articles` table.
|
809
809
|
|
810
810
|
To generate this new column, run this command within the engine:
|
811
811
|
|
812
812
|
```bash
|
813
|
-
$ bin/rails g migration
|
813
|
+
$ bin/rails g migration add_author_id_to_blorgh_articles author_id:integer
|
814
814
|
```
|
815
815
|
|
816
816
|
NOTE: Due to the migration's name and the column specification after it, Rails
|
@@ -822,41 +822,39 @@ This migration will need to be run on the application. To do that, it must first
|
|
822
822
|
be copied using this command:
|
823
823
|
|
824
824
|
```bash
|
825
|
-
$
|
825
|
+
$ rake blorgh:install:migrations
|
826
826
|
```
|
827
827
|
|
828
828
|
Notice that only _one_ migration was copied over here. This is because the first
|
829
829
|
two migrations were copied over the first time this command was run.
|
830
830
|
|
831
|
-
```
|
832
|
-
NOTE Migration [timestamp]
|
833
|
-
skipped. Migration with the same name already exists.
|
834
|
-
[timestamp]
|
835
|
-
with the same name already exists. Copied migration
|
836
|
-
[timestamp]_add_author_id_to_blorgh_posts.rb from blorgh
|
831
|
+
```
|
832
|
+
NOTE Migration [timestamp]_create_blorgh_articles.blorgh.rb from blorgh has been skipped. Migration with the same name already exists.
|
833
|
+
NOTE Migration [timestamp]_create_blorgh_comments.blorgh.rb from blorgh has been skipped. Migration with the same name already exists.
|
834
|
+
Copied migration [timestamp]_add_author_id_to_blorgh_articles.blorgh.rb from blorgh
|
837
835
|
```
|
838
836
|
|
839
837
|
Run the migration using:
|
840
838
|
|
841
839
|
```bash
|
842
|
-
$
|
840
|
+
$ rake db:migrate
|
843
841
|
```
|
844
842
|
|
845
843
|
Now with all the pieces in place, an action will take place that will associate
|
846
|
-
an author - represented by a record in the `users` table - with
|
847
|
-
represented by the `
|
844
|
+
an author - represented by a record in the `users` table - with an article,
|
845
|
+
represented by the `blorgh_articles` table from the engine.
|
848
846
|
|
849
|
-
Finally, the author's name should be displayed on the
|
850
|
-
above the "Title" output inside `app/views/blorgh/
|
847
|
+
Finally, the author's name should be displayed on the article's page. Add this code
|
848
|
+
above the "Title" output inside `app/views/blorgh/articles/show.html.erb`:
|
851
849
|
|
852
850
|
```html+erb
|
853
851
|
<p>
|
854
852
|
<b>Author:</b>
|
855
|
-
<%= @
|
853
|
+
<%= @article.author %>
|
856
854
|
</p>
|
857
855
|
```
|
858
856
|
|
859
|
-
By outputting `@
|
857
|
+
By outputting `@article.author` using the `<%=` tag, the `to_s` method will be
|
860
858
|
called on the object. By default, this will look quite ugly:
|
861
859
|
|
862
860
|
```
|
@@ -888,7 +886,9 @@ engine this would be done by changing
|
|
888
886
|
`app/controllers/blorgh/application_controller.rb` to look like:
|
889
887
|
|
890
888
|
```ruby
|
891
|
-
|
889
|
+
module Blorgh
|
890
|
+
class ApplicationController < ::ApplicationController
|
891
|
+
end
|
892
892
|
end
|
893
893
|
```
|
894
894
|
|
@@ -925,15 +925,15 @@ This method works like its brothers, `attr_accessor` and `cattr_accessor`, but
|
|
925
925
|
provides a setter and getter method on the module with the specified name. To
|
926
926
|
use it, it must be referenced using `Blorgh.author_class`.
|
927
927
|
|
928
|
-
The next step is to switch the `Blorgh::
|
928
|
+
The next step is to switch the `Blorgh::Article` model over to this new setting.
|
929
929
|
Change the `belongs_to` association inside this model
|
930
|
-
(`app/models/blorgh/
|
930
|
+
(`app/models/blorgh/article.rb`) to this:
|
931
931
|
|
932
932
|
```ruby
|
933
933
|
belongs_to :author, class_name: Blorgh.author_class
|
934
934
|
```
|
935
935
|
|
936
|
-
The `set_author` method in the `Blorgh::
|
936
|
+
The `set_author` method in the `Blorgh::Article` model should also use this class:
|
937
937
|
|
938
938
|
```ruby
|
939
939
|
self.author = Blorgh.author_class.constantize.find_or_create_by(name: author_name)
|
@@ -960,7 +960,7 @@ Resulting in something a little shorter, and more implicit in its behavior. The
|
|
960
960
|
`author_class` method should always return a `Class` object.
|
961
961
|
|
962
962
|
Since we changed the `author_class` method to return a `Class` instead of a
|
963
|
-
`String`, we must also modify our `belongs_to` definition in the `Blorgh::
|
963
|
+
`String`, we must also modify our `belongs_to` definition in the `Blorgh::Article`
|
964
964
|
model:
|
965
965
|
|
966
966
|
```ruby
|
@@ -985,14 +985,14 @@ to load that class and then reference the related table. This could lead to
|
|
985
985
|
problems if the table wasn't already existing. Therefore, a `String` should be
|
986
986
|
used and then converted to a class using `constantize` in the engine later on.
|
987
987
|
|
988
|
-
Go ahead and try to create a new
|
988
|
+
Go ahead and try to create a new article. You will see that it works exactly in the
|
989
989
|
same way as before, except this time the engine is using the configuration
|
990
990
|
setting in `config/initializers/blorgh.rb` to learn what the class is.
|
991
991
|
|
992
992
|
There are now no strict dependencies on what the class is, only what the API for
|
993
993
|
the class must be. The engine simply requires this class to define a
|
994
994
|
`find_or_create_by` method which returns an object of that class, to be
|
995
|
-
associated with
|
995
|
+
associated with an article when it's created. This object, of course, should have
|
996
996
|
some sort of identifier by which it can be referenced.
|
997
997
|
|
998
998
|
#### General Engine Configuration
|
@@ -1036,22 +1036,43 @@ functionality, especially controllers. This means that if you were to make a
|
|
1036
1036
|
typical `GET` to a controller in a controller's functional test like this:
|
1037
1037
|
|
1038
1038
|
```ruby
|
1039
|
-
|
1039
|
+
module Blorgh
|
1040
|
+
class FooControllerTest < ActionController::TestCase
|
1041
|
+
def test_index
|
1042
|
+
get :index
|
1043
|
+
...
|
1044
|
+
end
|
1045
|
+
end
|
1046
|
+
end
|
1040
1047
|
```
|
1041
1048
|
|
1042
1049
|
It may not function correctly. This is because the application doesn't know how
|
1043
1050
|
to route these requests to the engine unless you explicitly tell it **how**. To
|
1044
|
-
do this, you must
|
1045
|
-
|
1051
|
+
do this, you must set the `@routes` instance variable to the engine's route set
|
1052
|
+
in your setup code:
|
1046
1053
|
|
1047
1054
|
```ruby
|
1048
|
-
|
1055
|
+
module Blorgh
|
1056
|
+
class FooControllerTest < ActionController::TestCase
|
1057
|
+
setup do
|
1058
|
+
@routes = Engine.routes
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
def test_index
|
1062
|
+
get :index
|
1063
|
+
...
|
1064
|
+
end
|
1065
|
+
end
|
1066
|
+
end
|
1049
1067
|
```
|
1050
1068
|
|
1051
1069
|
This tells the application that you still want to perform a `GET` request to the
|
1052
1070
|
`index` action of this controller, but you want to use the engine's route to get
|
1053
1071
|
there, rather than the application's one.
|
1054
1072
|
|
1073
|
+
This also ensures that the engine's URL helpers will work as expected in your
|
1074
|
+
tests.
|
1075
|
+
|
1055
1076
|
Improving engine functionality
|
1056
1077
|
------------------------------
|
1057
1078
|
|
@@ -1097,12 +1118,12 @@ that isn't referenced by your main application.
|
|
1097
1118
|
|
1098
1119
|
#### Implementing Decorator Pattern Using Class#class_eval
|
1099
1120
|
|
1100
|
-
**Adding** `
|
1121
|
+
**Adding** `Article#time_since_created`:
|
1101
1122
|
|
1102
1123
|
```ruby
|
1103
|
-
# MyApp/app/decorators/models/blorgh/
|
1124
|
+
# MyApp/app/decorators/models/blorgh/article_decorator.rb
|
1104
1125
|
|
1105
|
-
Blorgh::
|
1126
|
+
Blorgh::Article.class_eval do
|
1106
1127
|
def time_since_created
|
1107
1128
|
Time.current - created_at
|
1108
1129
|
end
|
@@ -1110,20 +1131,20 @@ end
|
|
1110
1131
|
```
|
1111
1132
|
|
1112
1133
|
```ruby
|
1113
|
-
# Blorgh/app/models/
|
1134
|
+
# Blorgh/app/models/article.rb
|
1114
1135
|
|
1115
|
-
class
|
1136
|
+
class Article < ActiveRecord::Base
|
1116
1137
|
has_many :comments
|
1117
1138
|
end
|
1118
1139
|
```
|
1119
1140
|
|
1120
1141
|
|
1121
|
-
**Overriding** `
|
1142
|
+
**Overriding** `Article#summary`:
|
1122
1143
|
|
1123
1144
|
```ruby
|
1124
|
-
# MyApp/app/decorators/models/blorgh/
|
1145
|
+
# MyApp/app/decorators/models/blorgh/article_decorator.rb
|
1125
1146
|
|
1126
|
-
Blorgh::
|
1147
|
+
Blorgh::Article.class_eval do
|
1127
1148
|
def summary
|
1128
1149
|
"#{title} - #{truncate(text)}"
|
1129
1150
|
end
|
@@ -1131,9 +1152,9 @@ end
|
|
1131
1152
|
```
|
1132
1153
|
|
1133
1154
|
```ruby
|
1134
|
-
# Blorgh/app/models/
|
1155
|
+
# Blorgh/app/models/article.rb
|
1135
1156
|
|
1136
|
-
class
|
1157
|
+
class Article < ActiveRecord::Base
|
1137
1158
|
has_many :comments
|
1138
1159
|
def summary
|
1139
1160
|
"#{title}"
|
@@ -1145,17 +1166,17 @@ end
|
|
1145
1166
|
|
1146
1167
|
Using `Class#class_eval` is great for simple adjustments, but for more complex
|
1147
1168
|
class modifications, you might want to consider using [`ActiveSupport::Concern`]
|
1148
|
-
(http://
|
1169
|
+
(http://api.rubyonrails.org/classes/ActiveSupport/Concern.html).
|
1149
1170
|
ActiveSupport::Concern manages load order of interlinked dependent modules and
|
1150
1171
|
classes at run time allowing you to significantly modularize your code.
|
1151
1172
|
|
1152
|
-
**Adding** `
|
1173
|
+
**Adding** `Article#time_since_created` and **Overriding** `Article#summary`:
|
1153
1174
|
|
1154
1175
|
```ruby
|
1155
|
-
# MyApp/app/models/blorgh/
|
1176
|
+
# MyApp/app/models/blorgh/article.rb
|
1156
1177
|
|
1157
|
-
class Blorgh::
|
1158
|
-
include Blorgh::Concerns::Models::
|
1178
|
+
class Blorgh::Article < ActiveRecord::Base
|
1179
|
+
include Blorgh::Concerns::Models::Article
|
1159
1180
|
|
1160
1181
|
def time_since_created
|
1161
1182
|
Time.current - created_at
|
@@ -1168,22 +1189,22 @@ end
|
|
1168
1189
|
```
|
1169
1190
|
|
1170
1191
|
```ruby
|
1171
|
-
# Blorgh/app/models/
|
1192
|
+
# Blorgh/app/models/article.rb
|
1172
1193
|
|
1173
|
-
class
|
1174
|
-
include Blorgh::Concerns::Models::
|
1194
|
+
class Article < ActiveRecord::Base
|
1195
|
+
include Blorgh::Concerns::Models::Article
|
1175
1196
|
end
|
1176
1197
|
```
|
1177
1198
|
|
1178
1199
|
```ruby
|
1179
|
-
# Blorgh/lib/concerns/models/
|
1200
|
+
# Blorgh/lib/concerns/models/article
|
1180
1201
|
|
1181
|
-
module Blorgh::Concerns::Models::
|
1202
|
+
module Blorgh::Concerns::Models::Article
|
1182
1203
|
extend ActiveSupport::Concern
|
1183
1204
|
|
1184
1205
|
# 'included do' causes the included code to be evaluated in the
|
1185
|
-
# context where it is included (
|
1186
|
-
# executed in the module's context (blorgh/concerns/models/
|
1206
|
+
# context where it is included (article.rb), rather than being
|
1207
|
+
# executed in the module's context (blorgh/concerns/models/article).
|
1187
1208
|
included do
|
1188
1209
|
attr_accessor :author_name
|
1189
1210
|
belongs_to :author, class_name: "User"
|
@@ -1214,25 +1235,25 @@ When Rails looks for a view to render, it will first look in the `app/views`
|
|
1214
1235
|
directory of the application. If it cannot find the view there, it will check in
|
1215
1236
|
the `app/views` directories of all engines that have this directory.
|
1216
1237
|
|
1217
|
-
When the application is asked to render the view for `Blorgh::
|
1238
|
+
When the application is asked to render the view for `Blorgh::ArticlesController`'s
|
1218
1239
|
index action, it will first look for the path
|
1219
|
-
`app/views/blorgh/
|
1240
|
+
`app/views/blorgh/articles/index.html.erb` within the application. If it cannot
|
1220
1241
|
find it, it will look inside the engine.
|
1221
1242
|
|
1222
1243
|
You can override this view in the application by simply creating a new file at
|
1223
|
-
`app/views/blorgh/
|
1244
|
+
`app/views/blorgh/articles/index.html.erb`. Then you can completely change what
|
1224
1245
|
this view would normally output.
|
1225
1246
|
|
1226
|
-
Try this now by creating a new file at `app/views/blorgh/
|
1247
|
+
Try this now by creating a new file at `app/views/blorgh/articles/index.html.erb`
|
1227
1248
|
and put this content in it:
|
1228
1249
|
|
1229
1250
|
```html+erb
|
1230
|
-
<h1>
|
1231
|
-
<%= link_to "New
|
1232
|
-
<% @
|
1233
|
-
<h2><%=
|
1234
|
-
<small>By <%=
|
1235
|
-
<%= simple_format(
|
1251
|
+
<h1>Articles</h1>
|
1252
|
+
<%= link_to "New Article", new_article_path %>
|
1253
|
+
<% @articles.each do |article| %>
|
1254
|
+
<h2><%= article.title %></h2>
|
1255
|
+
<small>By <%= article.author %></small>
|
1256
|
+
<%= simple_format(article.text) %>
|
1236
1257
|
<hr>
|
1237
1258
|
<% end %>
|
1238
1259
|
```
|
@@ -1249,30 +1270,30 @@ Routes inside an engine are drawn on the `Engine` class within
|
|
1249
1270
|
|
1250
1271
|
```ruby
|
1251
1272
|
Blorgh::Engine.routes.draw do
|
1252
|
-
resources :
|
1273
|
+
resources :articles
|
1253
1274
|
end
|
1254
1275
|
```
|
1255
1276
|
|
1256
1277
|
By having isolated routes such as this, if you wish to link to an area of an
|
1257
1278
|
engine from within an application, you will need to use the engine's routing
|
1258
|
-
proxy method. Calls to normal routing methods such as `
|
1279
|
+
proxy method. Calls to normal routing methods such as `articles_path` may end up
|
1259
1280
|
going to undesired locations if both the application and the engine have such a
|
1260
1281
|
helper defined.
|
1261
1282
|
|
1262
|
-
For instance, the following example would go to the application's `
|
1263
|
-
if that template was rendered from the application, or the engine's `
|
1283
|
+
For instance, the following example would go to the application's `articles_path`
|
1284
|
+
if that template was rendered from the application, or the engine's `articles_path`
|
1264
1285
|
if it was rendered from the engine:
|
1265
1286
|
|
1266
1287
|
```erb
|
1267
|
-
<%= link_to "Blog
|
1288
|
+
<%= link_to "Blog articles", articles_path %>
|
1268
1289
|
```
|
1269
1290
|
|
1270
|
-
To make this route always use the engine's `
|
1291
|
+
To make this route always use the engine's `articles_path` routing helper method,
|
1271
1292
|
we must call the method on the routing proxy method that shares the same name as
|
1272
1293
|
the engine.
|
1273
1294
|
|
1274
1295
|
```erb
|
1275
|
-
<%= link_to "Blog
|
1296
|
+
<%= link_to "Blog articles", blorgh.articles_path %>
|
1276
1297
|
```
|
1277
1298
|
|
1278
1299
|
If you wish to reference the application inside the engine in a similar way, use
|