diff options
Diffstat (limited to 'guides/source/engines.md')
-rw-r--r-- | guides/source/engines.md | 114 |
1 files changed, 48 insertions, 66 deletions
diff --git a/guides/source/engines.md b/guides/source/engines.md index a5f8ee27b8..f961b799f1 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -1,3 +1,5 @@ +**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.** + Getting Started with Engines ============================ @@ -32,7 +34,7 @@ directory structure, and are both generated using the `rails plugin new` generator. The difference is that an engine is considered a "full plugin" by Rails (as indicated by the `--full` option that's passed to the generator command). We'll actually be using the `--mountable` option here, which includes -all the features of `--full`, and then some. This guide will refer to these +all the features of `--full`, and then some. This guide will refer to these "full plugins" simply as "engines" throughout. An engine **can** be a plugin, and a plugin **can** be an engine. @@ -74,13 +76,13 @@ options as appropriate to the need. For the "blorgh" example, you will need to create a "mountable" engine, running this command in a terminal: ```bash -$ bin/rails plugin new blorgh --mountable +$ rails plugin new blorgh --mountable ``` The full list of options for the plugin generator may be seen by typing: ```bash -$ bin/rails plugin --help +$ rails plugin --help ``` The `--mountable` option tells the generator that you want to create a @@ -136,7 +138,7 @@ following to the dummy application's routes file at `test/dummy/config/routes.rb`: ```ruby -mount Blorgh::Engine, at: "blorgh" +mount Blorgh::Engine => "/blorgh" ``` ### Inside an Engine @@ -148,7 +150,7 @@ When you include the engine into an application later on, you will do so with this line in the Rails application's `Gemfile`: ```ruby -gem 'blorgh', path: "vendor/engines/blorgh" +gem 'blorgh', path: 'engines/blorgh' ``` Don't forget to run `bundle install` as usual. By specifying it as a gem within @@ -173,7 +175,7 @@ Within `lib/blorgh/engine.rb` is the base class for the engine: ```ruby module Blorgh - class Engine < Rails::Engine + class Engine < ::Rails::Engine isolate_namespace Blorgh end end @@ -322,8 +324,6 @@ invoke test_unit create test/controllers/blorgh/articles_controller_test.rb invoke helper create app/helpers/blorgh/articles_helper.rb -invoke test_unit -create test/helpers/blorgh/articles_helper_test.rb invoke assets invoke js create app/assets/javascripts/blorgh/articles.js @@ -368,7 +368,7 @@ called `Blorgh::ArticlesController` (at `app/controllers/blorgh/articles_controller.rb`) and its related views at `app/views/blorgh/articles`. This generator also generates a test for the controller (`test/controllers/blorgh/articles_controller_test.rb`) and a helper -(`app/helpers/blorgh/articles_controller.rb`). +(`app/helpers/blorgh/articles_helper.rb`). Everything this generator has created is neatly namespaced. The controller's class is defined within the `Blorgh` module: @@ -402,15 +402,6 @@ Finally, the assets for this resource are generated in two files: `app/assets/stylesheets/blorgh/articles.css`. You'll see how to use these a little later. -By default, the scaffold styling is not applied to the engine because the -engine's layout file, `app/views/layouts/blorgh/application.html.erb`, doesn't -load it. To make the scaffold styling apply, insert this line into the `<head>` -tag of this layout: - -```erb -<%= stylesheet_link_tag "scaffold" %> -``` - You can see what the engine has so far by running `rake db:migrate` at the root of our engine to run the migration generated by the scaffold generator, and then running `rails server` in `test/dummy`. When you open @@ -560,8 +551,6 @@ invoke test_unit create test/controllers/blorgh/comments_controller_test.rb invoke helper create app/helpers/blorgh/comments_helper.rb -invoke test_unit -create test/helpers/blorgh/comments_helper_test.rb invoke assets invoke js create app/assets/javascripts/blorgh/comments.js @@ -593,7 +582,7 @@ the comments, however, is not quite right yet. If you were to create a comment right now, you would see this error: ``` -Missing partial blorgh/comments/comment with {:handlers=>[:erb, :builder], +Missing partial blorgh/comments/_comment with {:handlers=>[:erb, :builder], :formats=>[:html], :locale=>[:en, :en]}. Searched in: * "/Users/ryan/Sites/side_projects/blorgh/test/dummy/app/views" * "/Users/ryan/Sites/side_projects/blorgh/app/views" @@ -602,7 +591,7 @@ Missing partial blorgh/comments/comment with {:handlers=>[:erb, :builder], The engine is unable to find the partial required for rendering the comments. Rails looks first in the application's (`test/dummy`) `app/views` directory and then in the engine's `app/views` directory. When it can't find it, it will throw -this error. The engine knows to look for `blorgh/comments/comment` because the +this error. The engine knows to look for `blorgh/comments/_comment` because the model object it is receiving is from the `Blorgh::Comment` class. This partial will be responsible for rendering just the comment text, for now. @@ -650,7 +639,7 @@ However, because you are developing the `blorgh` engine on your local machine, you will need to specify the `:path` option in your `Gemfile`: ```ruby -gem 'blorgh', path: "/path/to/blorgh" +gem 'blorgh', path: 'engines/blorgh' ``` Then run `bundle` to install the gem. @@ -681,7 +670,7 @@ pre-defined path which may be customizable. The engine contains migrations for the `blorgh_articles` and `blorgh_comments` table which need to be created in the application's database so that the engine's models can query them correctly. To copy these migrations into the -application use this command: +application run the following command from the `test/dummy` directory of your Rails engine: ```bash $ rake blorgh:install:migrations @@ -700,8 +689,8 @@ haven't been copied over already. The first run for this command will output something such as this: ```bash -Copied migration [timestamp_1]_create_blorgh_articles.rb from blorgh -Copied migration [timestamp_2]_create_blorgh_comments.rb from blorgh +Copied migration [timestamp_1]_create_blorgh_articles.blorgh.rb from blorgh +Copied migration [timestamp_2]_create_blorgh_comments.blorgh.rb from blorgh ``` The first timestamp (`[timestamp_1]`) will be the current time, and the second @@ -833,11 +822,9 @@ Notice that only _one_ migration was copied over here. This is because the first two migrations were copied over the first time this command was run. ``` -NOTE Migration [timestamp]_create_blorgh_articles.rb from blorgh has been -skipped. Migration with the same name already exists. NOTE Migration -[timestamp]_create_blorgh_comments.rb from blorgh has been skipped. Migration -with the same name already exists. Copied migration -[timestamp]_add_author_id_to_blorgh_articles.rb from blorgh +NOTE Migration [timestamp]_create_blorgh_articles.blorgh.rb from blorgh has been skipped. Migration with the same name already exists. +NOTE Migration [timestamp]_create_blorgh_comments.blorgh.rb from blorgh has been skipped. Migration with the same name already exists. +Copied migration [timestamp]_add_author_id_to_blorgh_articles.blorgh.rb from blorgh ``` Run the migration using: @@ -856,28 +843,10 @@ above the "Title" output inside `app/views/blorgh/articles/show.html.erb`: ```html+erb <p> <b>Author:</b> - <%= @article.author %> + <%= @article.author.name %> </p> ``` -By outputting `@article.author` using the `<%=` tag, the `to_s` method will be -called on the object. By default, this will look quite ugly: - -``` -#<User:0x00000100ccb3b0> -``` - -This is undesirable. It would be much better to have the user's name there. To -do this, add a `to_s` method to the `User` class within the application: - -```ruby -def to_s - name -end -``` - -Now instead of the ugly Ruby object output, the author's name will be displayed. - #### Using a Controller Provided by the Application Because Rails controllers generally share code for things like authentication @@ -892,7 +861,9 @@ engine this would be done by changing `app/controllers/blorgh/application_controller.rb` to look like: ```ruby -class Blorgh::ApplicationController < ApplicationController +module Blorgh + class ApplicationController < ::ApplicationController + end end ``` @@ -1040,31 +1011,42 @@ functionality, especially controllers. This means that if you were to make a typical `GET` to a controller in a controller's functional test like this: ```ruby -get :index +module Blorgh + class FooControllerTest < ActionController::TestCase + def test_index + get :index + ... + end + end +end ``` It may not function correctly. This is because the application doesn't know how to route these requests to the engine unless you explicitly tell it **how**. To -do this, you must also pass the `:use_route` option as a parameter on these -requests: +do this, you must set the `@routes` instance variable to the engine's route set +in your setup code: ```ruby -get :index, use_route: :blorgh +module Blorgh + class FooControllerTest < ActionController::TestCase + setup do + @routes = Engine.routes + end + + def test_index + get :index + ... + end + end +end ``` This tells the application that you still want to perform a `GET` request to the `index` action of this controller, but you want to use the engine's route to get there, rather than the application's one. -Another way to do this is to assign the `@routes` instance variable to `Engine.routes` in your test setup: - -```ruby -setup do - @routes = Engine.routes -end -``` - -This will also ensure url helpers for the engine will work as expected in your tests. +This also ensures that the engine's URL helpers will work as expected in your +tests. Improving engine functionality ------------------------------ @@ -1159,7 +1141,7 @@ end Using `Class#class_eval` is great for simple adjustments, but for more complex class modifications, you might want to consider using [`ActiveSupport::Concern`] -(http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html). +(http://api.rubyonrails.org/classes/ActiveSupport/Concern.html). ActiveSupport::Concern manages load order of interlinked dependent modules and classes at run time allowing you to significantly modularize your code. @@ -1190,7 +1172,7 @@ end ``` ```ruby -# Blorgh/lib/concerns/models/article +# Blorgh/lib/concerns/models/article.rb module Blorgh::Concerns::Models::Article extend ActiveSupport::Concern |