rails 4.2.0.beta3 → 4.2.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -7
  3. data/guides/output/2_2_release_notes.html +724 -0
  4. data/guides/output/2_3_release_notes.html +870 -0
  5. data/guides/output/3_0_release_notes.html +773 -0
  6. data/guides/output/3_1_release_notes.html +740 -0
  7. data/guides/output/3_2_release_notes.html +797 -0
  8. data/guides/output/4_0_release_notes.html +523 -0
  9. data/guides/output/4_1_release_notes.html +806 -0
  10. data/guides/output/4_2_release_notes.html +728 -0
  11. data/guides/output/Gemfile +6 -0
  12. data/guides/output/_license.html +226 -0
  13. data/guides/output/_welcome.html +233 -0
  14. data/guides/output/action_controller_overview.html +1335 -0
  15. data/guides/output/action_mailer_basics.html +928 -0
  16. data/guides/output/action_view_overview.html +1509 -0
  17. data/guides/output/active_job_basics.html +546 -0
  18. data/guides/output/active_model_basics.html +438 -0
  19. data/guides/output/active_record_basics.html +594 -0
  20. data/guides/output/active_record_callbacks.html +592 -0
  21. data/guides/output/active_record_migrations.html +1123 -0
  22. data/guides/output/active_record_postgresql.html +675 -0
  23. data/guides/output/active_record_querying.html +1796 -0
  24. data/guides/output/active_record_validations.html +1301 -0
  25. data/guides/output/active_support_core_extensions.html +3450 -0
  26. data/guides/output/active_support_instrumentation.html +1121 -0
  27. data/guides/output/api_documentation_guidelines.html +498 -0
  28. data/guides/output/asset_pipeline.html +1167 -0
  29. data/guides/output/association_basics.html +2086 -0
  30. data/guides/output/caching_with_rails.html +553 -0
  31. data/guides/output/command_line.html +791 -0
  32. data/guides/output/configuring.html +1055 -0
  33. data/guides/output/contributing_to_ruby_on_rails.html +657 -0
  34. data/guides/output/credits.html +284 -0
  35. data/guides/output/debugging_rails_applications.html +1014 -0
  36. data/guides/output/development_dependencies_install.html +478 -0
  37. data/guides/output/engines.html +1438 -0
  38. data/guides/output/form_helpers.html +1074 -0
  39. data/guides/output/generators.html +838 -0
  40. data/guides/output/getting_started.html +2092 -0
  41. data/guides/output/i18n.html +1198 -0
  42. data/guides/output/images/akshaysurve.jpg +0 -0
  43. data/guides/output/images/belongs_to.png +0 -0
  44. data/guides/output/images/book_icon.gif +0 -0
  45. data/guides/output/images/bullet.gif +0 -0
  46. data/guides/output/images/chapters_icon.gif +0 -0
  47. data/guides/output/images/check_bullet.gif +0 -0
  48. data/guides/output/images/credits_pic_blank.gif +0 -0
  49. data/guides/output/images/csrf.png +0 -0
  50. data/guides/output/images/edge_badge.png +0 -0
  51. data/guides/output/images/favicon.ico +0 -0
  52. data/guides/output/images/feature_tile.gif +0 -0
  53. data/guides/output/images/footer_tile.gif +0 -0
  54. data/guides/output/images/fxn.png +0 -0
  55. data/guides/output/images/getting_started/article_with_comments.png +0 -0
  56. data/guides/output/images/getting_started/challenge.png +0 -0
  57. data/guides/output/images/getting_started/confirm_dialog.png +0 -0
  58. data/guides/output/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
  59. data/guides/output/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
  60. data/guides/output/images/getting_started/form_with_errors.png +0 -0
  61. data/guides/output/images/getting_started/index_action_with_edit_link.png +0 -0
  62. data/guides/output/images/getting_started/new_article.png +0 -0
  63. data/guides/output/images/getting_started/new_post.png +0 -0
  64. data/guides/output/images/getting_started/post_with_comments.png +0 -0
  65. data/guides/output/images/getting_started/rails_welcome.png +0 -0
  66. data/guides/output/images/getting_started/routing_error_no_controller.png +0 -0
  67. data/guides/output/images/getting_started/routing_error_no_route_matches.png +0 -0
  68. data/guides/output/images/getting_started/show_action_for_articles.png +0 -0
  69. data/guides/output/images/getting_started/show_action_for_posts.png +0 -0
  70. data/guides/output/images/getting_started/template_is_missing_articles_new.png +0 -0
  71. data/guides/output/images/getting_started/template_is_missing_posts_new.png +0 -0
  72. data/guides/output/images/getting_started/undefined_method_post_path.png +0 -0
  73. data/guides/output/images/getting_started/unknown_action_create_for_articles.png +0 -0
  74. data/guides/output/images/getting_started/unknown_action_create_for_posts.png +0 -0
  75. data/guides/output/images/getting_started/unknown_action_new_for_articles.png +0 -0
  76. data/guides/output/images/getting_started/unknown_action_new_for_posts.png +0 -0
  77. data/guides/output/images/grey_bullet.gif +0 -0
  78. data/guides/output/images/habtm.png +0 -0
  79. data/guides/output/images/has_many.png +0 -0
  80. data/guides/output/images/has_many_through.png +0 -0
  81. data/guides/output/images/has_one.png +0 -0
  82. data/guides/output/images/has_one_through.png +0 -0
  83. data/guides/output/images/header_backdrop.png +0 -0
  84. data/guides/output/images/header_tile.gif +0 -0
  85. data/guides/output/images/i18n/demo_html_safe.png +0 -0
  86. data/guides/output/images/i18n/demo_localized_pirate.png +0 -0
  87. data/guides/output/images/i18n/demo_translated_en.png +0 -0
  88. data/guides/output/images/i18n/demo_translated_pirate.png +0 -0
  89. data/guides/output/images/i18n/demo_translation_missing.png +0 -0
  90. data/guides/output/images/i18n/demo_untranslated.png +0 -0
  91. data/guides/output/images/icons/README +5 -0
  92. data/guides/output/images/icons/callouts/1.png +0 -0
  93. data/guides/output/images/icons/callouts/10.png +0 -0
  94. data/guides/output/images/icons/callouts/11.png +0 -0
  95. data/guides/output/images/icons/callouts/12.png +0 -0
  96. data/guides/output/images/icons/callouts/13.png +0 -0
  97. data/guides/output/images/icons/callouts/14.png +0 -0
  98. data/guides/output/images/icons/callouts/15.png +0 -0
  99. data/guides/output/images/icons/callouts/2.png +0 -0
  100. data/guides/output/images/icons/callouts/3.png +0 -0
  101. data/guides/output/images/icons/callouts/4.png +0 -0
  102. data/guides/output/images/icons/callouts/5.png +0 -0
  103. data/guides/output/images/icons/callouts/6.png +0 -0
  104. data/guides/output/images/icons/callouts/7.png +0 -0
  105. data/guides/output/images/icons/callouts/8.png +0 -0
  106. data/guides/output/images/icons/callouts/9.png +0 -0
  107. data/guides/output/images/icons/caution.png +0 -0
  108. data/guides/output/images/icons/example.png +0 -0
  109. data/guides/output/images/icons/home.png +0 -0
  110. data/guides/output/images/icons/important.png +0 -0
  111. data/guides/output/images/icons/next.png +0 -0
  112. data/guides/output/images/icons/note.png +0 -0
  113. data/guides/output/images/icons/prev.png +0 -0
  114. data/guides/output/images/icons/tip.png +0 -0
  115. data/guides/output/images/icons/up.png +0 -0
  116. data/guides/output/images/icons/warning.png +0 -0
  117. data/guides/output/images/nav_arrow.gif +0 -0
  118. data/guides/output/images/oscardelben.jpg +0 -0
  119. data/guides/output/images/polymorphic.png +0 -0
  120. data/guides/output/images/radar.png +0 -0
  121. data/guides/output/images/rails4_features.png +0 -0
  122. data/guides/output/images/rails_guides_kindle_cover.jpg +0 -0
  123. data/guides/output/images/rails_guides_logo.gif +0 -0
  124. data/guides/output/images/rails_logo_remix.gif +0 -0
  125. data/guides/output/images/session_fixation.png +0 -0
  126. data/guides/output/images/tab_grey.gif +0 -0
  127. data/guides/output/images/tab_info.gif +0 -0
  128. data/guides/output/images/tab_note.gif +0 -0
  129. data/guides/output/images/tab_red.gif +0 -0
  130. data/guides/output/images/tab_yellow.gif +0 -0
  131. data/guides/output/images/tab_yellow.png +0 -0
  132. data/guides/output/images/vijaydev.jpg +0 -0
  133. data/guides/output/index.html +354 -0
  134. data/guides/output/initialization.html +876 -0
  135. data/guides/output/javascripts/guides.js +59 -0
  136. data/guides/output/javascripts/jquery.min.js +4 -0
  137. data/guides/output/javascripts/responsive-tables.js +43 -0
  138. data/guides/output/javascripts/syntaxhighlighter/shBrushAS3.js +59 -0
  139. data/guides/output/javascripts/syntaxhighlighter/shBrushAppleScript.js +75 -0
  140. data/guides/output/javascripts/syntaxhighlighter/shBrushBash.js +59 -0
  141. data/guides/output/javascripts/syntaxhighlighter/shBrushCSharp.js +65 -0
  142. data/guides/output/javascripts/syntaxhighlighter/shBrushColdFusion.js +100 -0
  143. data/guides/output/javascripts/syntaxhighlighter/shBrushCpp.js +97 -0
  144. data/guides/output/javascripts/syntaxhighlighter/shBrushCss.js +91 -0
  145. data/guides/output/javascripts/syntaxhighlighter/shBrushDelphi.js +55 -0
  146. data/guides/output/javascripts/syntaxhighlighter/shBrushDiff.js +41 -0
  147. data/guides/output/javascripts/syntaxhighlighter/shBrushErlang.js +52 -0
  148. data/guides/output/javascripts/syntaxhighlighter/shBrushGroovy.js +67 -0
  149. data/guides/output/javascripts/syntaxhighlighter/shBrushJScript.js +52 -0
  150. data/guides/output/javascripts/syntaxhighlighter/shBrushJava.js +57 -0
  151. data/guides/output/javascripts/syntaxhighlighter/shBrushJavaFX.js +58 -0
  152. data/guides/output/javascripts/syntaxhighlighter/shBrushPerl.js +72 -0
  153. data/guides/output/javascripts/syntaxhighlighter/shBrushPhp.js +88 -0
  154. data/guides/output/javascripts/syntaxhighlighter/shBrushPlain.js +33 -0
  155. data/guides/output/javascripts/syntaxhighlighter/shBrushPowerShell.js +74 -0
  156. data/guides/output/javascripts/syntaxhighlighter/shBrushPython.js +64 -0
  157. data/guides/output/javascripts/syntaxhighlighter/shBrushRuby.js +55 -0
  158. data/guides/output/javascripts/syntaxhighlighter/shBrushSass.js +94 -0
  159. data/guides/output/javascripts/syntaxhighlighter/shBrushScala.js +51 -0
  160. data/guides/output/javascripts/syntaxhighlighter/shBrushSql.js +66 -0
  161. data/guides/output/javascripts/syntaxhighlighter/shBrushVb.js +56 -0
  162. data/guides/output/javascripts/syntaxhighlighter/shBrushXml.js +69 -0
  163. data/guides/output/javascripts/syntaxhighlighter/shCore.js +17 -0
  164. data/guides/output/layout.html +448 -0
  165. data/guides/output/layouts_and_rendering.html +1541 -0
  166. data/guides/output/maintenance_policy.html +257 -0
  167. data/guides/output/migrations.html +1360 -0
  168. data/guides/output/nested_model_forms.html +412 -0
  169. data/guides/output/plugins.html +644 -0
  170. data/guides/output/rails_application_templates.html +450 -0
  171. data/guides/output/rails_on_rack.html +547 -0
  172. data/guides/output/routing.html +1631 -0
  173. data/guides/output/ruby_on_rails_guides_guidelines.html +329 -0
  174. data/guides/output/security.html +935 -0
  175. data/guides/output/stylesheets/fixes.css +16 -0
  176. data/guides/output/stylesheets/kindle.css +11 -0
  177. data/guides/output/stylesheets/main.css +713 -0
  178. data/guides/output/stylesheets/print.css +52 -0
  179. data/guides/output/stylesheets/reset.css +43 -0
  180. data/guides/output/stylesheets/responsive-tables.css +50 -0
  181. data/guides/output/stylesheets/style.css +13 -0
  182. data/guides/output/stylesheets/syntaxhighlighter/shCore.css +226 -0
  183. data/guides/output/stylesheets/syntaxhighlighter/shCoreDefault.css +328 -0
  184. data/guides/output/stylesheets/syntaxhighlighter/shCoreDjango.css +331 -0
  185. data/guides/output/stylesheets/syntaxhighlighter/shCoreEclipse.css +339 -0
  186. data/guides/output/stylesheets/syntaxhighlighter/shCoreEmacs.css +324 -0
  187. data/guides/output/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +328 -0
  188. data/guides/output/stylesheets/syntaxhighlighter/shCoreMDUltra.css +324 -0
  189. data/guides/output/stylesheets/syntaxhighlighter/shCoreMidnight.css +324 -0
  190. data/guides/output/stylesheets/syntaxhighlighter/shCoreRDark.css +324 -0
  191. data/guides/output/stylesheets/syntaxhighlighter/shThemeDefault.css +117 -0
  192. data/guides/output/stylesheets/syntaxhighlighter/shThemeDjango.css +120 -0
  193. data/guides/output/stylesheets/syntaxhighlighter/shThemeEclipse.css +128 -0
  194. data/guides/output/stylesheets/syntaxhighlighter/shThemeEmacs.css +113 -0
  195. data/guides/output/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +117 -0
  196. data/guides/output/stylesheets/syntaxhighlighter/shThemeMDUltra.css +113 -0
  197. data/guides/output/stylesheets/syntaxhighlighter/shThemeMidnight.css +113 -0
  198. data/guides/output/stylesheets/syntaxhighlighter/shThemeRDark.css +113 -0
  199. data/guides/output/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +116 -0
  200. data/guides/output/testing.html +1350 -0
  201. data/guides/output/upgrading_ruby_on_rails.html +1135 -0
  202. data/guides/output/working_with_javascript_in_rails.html +587 -0
  203. data/guides/source/4_0_release_notes.md +2 -2
  204. data/guides/source/4_2_release_notes.md +9 -2
  205. data/guides/source/action_controller_overview.md +3 -1
  206. data/guides/source/action_mailer_basics.md +1 -2
  207. data/guides/source/active_job_basics.md +25 -2
  208. data/guides/source/active_model_basics.md +350 -19
  209. data/guides/source/active_record_basics.md +2 -2
  210. data/guides/source/active_record_migrations.md +1 -1
  211. data/guides/source/active_record_validations.md +12 -4
  212. data/guides/source/active_support_core_extensions.md +7 -9
  213. data/guides/source/active_support_instrumentation.md +2 -0
  214. data/guides/source/association_basics.md +7 -7
  215. data/guides/source/configuring.md +24 -0
  216. data/guides/source/contributing_to_ruby_on_rails.md +1 -1
  217. data/guides/source/credits.html.erb +1 -1
  218. data/guides/source/documents.yaml +5 -0
  219. data/guides/source/engines.md +2 -2
  220. data/guides/source/form_helpers.md +6 -0
  221. data/guides/source/i18n.md +6 -9
  222. data/guides/source/layouts_and_rendering.md +1 -1
  223. data/guides/source/plugins.md +2 -2
  224. data/guides/source/rails_on_rack.md +4 -0
  225. data/guides/source/testing.md +1 -0
  226. data/guides/source/upgrading_ruby_on_rails.md +5 -5
  227. metadata +227 -27
@@ -0,0 +1,1438 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
7
+
8
+ <title>Getting Started with Engines — Ruby on Rails Guides</title>
9
+ <link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
10
+ <link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print" />
11
+
12
+ <link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shCore.css" />
13
+ <link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shThemeRailsGuides.css" />
14
+
15
+ <link rel="stylesheet" type="text/css" href="stylesheets/fixes.css" />
16
+
17
+ <link href="images/favicon.ico" rel="shortcut icon" type="image/x-icon" />
18
+ </head>
19
+ <body class="guide">
20
+ <div id="topNav">
21
+ <div class="wrapper">
22
+ <strong class="more-info-label">More at <a href="http://rubyonrails.org/">rubyonrails.org:</a> </strong>
23
+ <span class="red-button more-info-button">
24
+ More Ruby on Rails
25
+ </span>
26
+ <ul class="more-info-links s-hidden">
27
+ <li class="more-info"><a href="http://rubyonrails.org/">Overview</a></li>
28
+ <li class="more-info"><a href="http://rubyonrails.org/download">Download</a></li>
29
+ <li class="more-info"><a href="http://rubyonrails.org/deploy">Deploy</a></li>
30
+ <li class="more-info"><a href="https://github.com/rails/rails">Code</a></li>
31
+ <li class="more-info"><a href="http://rubyonrails.org/screencasts">Screencasts</a></li>
32
+ <li class="more-info"><a href="http://rubyonrails.org/documentation">Documentation</a></li>
33
+ <li class="more-info"><a href="http://rubyonrails.org/community">Community</a></li>
34
+ <li class="more-info"><a href="http://weblog.rubyonrails.org/">Blog</a></li>
35
+ </ul>
36
+ </div>
37
+ </div>
38
+ <div id="header">
39
+ <div class="wrapper clearfix">
40
+ <h1><a href="index.html" title="Return to home page">Guides.rubyonrails.org</a></h1>
41
+ <ul class="nav">
42
+ <li><a class="nav-item" href="index.html">Home</a></li>
43
+ <li class="guides-index guides-index-large">
44
+ <a href="index.html" id="guidesMenu" class="guides-index-item nav-item">Guides Index</a>
45
+ <div id="guides" class="clearfix" style="display: none;">
46
+ <hr />
47
+ <dl class="L">
48
+ <dt>Start Here</dt>
49
+ <dd><a href="getting_started.html">Getting Started with Rails</a></dd>
50
+ <dt>Models</dt>
51
+ <dd><a href="active_record_basics.html">Active Record Basics</a></dd>
52
+ <dd><a href="active_record_migrations.html">Active Record Migrations</a></dd>
53
+ <dd><a href="active_record_validations.html">Active Record Validations</a></dd>
54
+ <dd><a href="active_record_callbacks.html">Active Record Callbacks</a></dd>
55
+ <dd><a href="association_basics.html">Active Record Associations</a></dd>
56
+ <dd><a href="active_record_querying.html">Active Record Query Interface</a></dd>
57
+ <dt>Views</dt>
58
+ <dd><a href="layouts_and_rendering.html">Layouts and Rendering in Rails</a></dd>
59
+ <dd><a href="form_helpers.html">Action View Form Helpers</a></dd>
60
+ <dt>Controllers</dt>
61
+ <dd><a href="action_controller_overview.html">Action Controller Overview</a></dd>
62
+ <dd><a href="routing.html">Rails Routing from the Outside In</a></dd>
63
+ </dl>
64
+ <dl class="R">
65
+ <dt>Digging Deeper</dt>
66
+ <dd><a href="active_support_core_extensions.html">Active Support Core Extensions</a></dd>
67
+ <dd><a href="i18n.html">Rails Internationalization API</a></dd>
68
+ <dd><a href="action_mailer_basics.html">Action Mailer Basics</a></dd>
69
+ <dd><a href="active_job_basics.html">Active Job Basics</a></dd>
70
+ <dd><a href="security.html">Securing Rails Applications</a></dd>
71
+ <dd><a href="debugging_rails_applications.html">Debugging Rails Applications</a></dd>
72
+ <dd><a href="configuring.html">Configuring Rails Applications</a></dd>
73
+ <dd><a href="command_line.html">Rails Command Line Tools and Rake Tasks</a></dd>
74
+ <dd><a href="asset_pipeline.html">Asset Pipeline</a></dd>
75
+ <dd><a href="working_with_javascript_in_rails.html">Working with JavaScript in Rails</a></dd>
76
+ <dt>Extending Rails</dt>
77
+ <dd><a href="rails_on_rack.html">Rails on Rack</a></dd>
78
+ <dd><a href="generators.html">Creating and Customizing Rails Generators</a></dd>
79
+ <dt>Contributing to Ruby on Rails</dt>
80
+ <dd><a href="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</a></dd>
81
+ <dd><a href="api_documentation_guidelines.html">API Documentation Guidelines</a></dd>
82
+ <dd><a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a></dd>
83
+ <dt>Maintenance Policy</dt>
84
+ <dd><a href="maintenance_policy.html">Maintenance Policy</a></dd>
85
+ <dt>Release Notes</dt>
86
+ <dd><a href="upgrading_ruby_on_rails.html">Upgrading Ruby on Rails</a></dd>
87
+ <dd><a href="4_1_release_notes.html">Ruby on Rails 4.1 Release Notes</a></dd>
88
+ <dd><a href="4_0_release_notes.html">Ruby on Rails 4.0 Release Notes</a></dd>
89
+ <dd><a href="3_2_release_notes.html">Ruby on Rails 3.2 Release Notes</a></dd>
90
+ <dd><a href="3_1_release_notes.html">Ruby on Rails 3.1 Release Notes</a></dd>
91
+ <dd><a href="3_0_release_notes.html">Ruby on Rails 3.0 Release Notes</a></dd>
92
+ <dd><a href="2_3_release_notes.html">Ruby on Rails 2.3 Release Notes</a></dd>
93
+ <dd><a href="2_2_release_notes.html">Ruby on Rails 2.2 Release Notes</a></dd>
94
+ </dl>
95
+ </div>
96
+ </li>
97
+ <li><a class="nav-item" href="contributing_to_ruby_on_rails.html">Contribute</a></li>
98
+ <li><a class="nav-item" href="credits.html">Credits</a></li>
99
+ <li class="guides-index guides-index-small">
100
+ <select class="guides-index-item nav-item">
101
+ <option value="index.html">Guides Index</option>
102
+ <optgroup label="Start Here">
103
+ <option value="getting_started.html">Getting Started with Rails</option>
104
+ </optgroup>
105
+ <optgroup label="Models">
106
+ <option value="active_record_basics.html">Active Record Basics</option>
107
+ <option value="active_record_migrations.html">Active Record Migrations</option>
108
+ <option value="active_record_validations.html">Active Record Validations</option>
109
+ <option value="active_record_callbacks.html">Active Record Callbacks</option>
110
+ <option value="association_basics.html">Active Record Associations</option>
111
+ <option value="active_record_querying.html">Active Record Query Interface</option>
112
+ </optgroup>
113
+ <optgroup label="Views">
114
+ <option value="layouts_and_rendering.html">Layouts and Rendering in Rails</option>
115
+ <option value="form_helpers.html">Action View Form Helpers</option>
116
+ </optgroup>
117
+ <optgroup label="Controllers">
118
+ <option value="action_controller_overview.html">Action Controller Overview</option>
119
+ <option value="routing.html">Rails Routing from the Outside In</option>
120
+ </optgroup>
121
+ <optgroup label="Digging Deeper">
122
+ <option value="active_support_core_extensions.html">Active Support Core Extensions</option>
123
+ <option value="i18n.html">Rails Internationalization API</option>
124
+ <option value="action_mailer_basics.html">Action Mailer Basics</option>
125
+ <option value="active_job_basics.html">Active Job Basics</option>
126
+ <option value="security.html">Securing Rails Applications</option>
127
+ <option value="debugging_rails_applications.html">Debugging Rails Applications</option>
128
+ <option value="configuring.html">Configuring Rails Applications</option>
129
+ <option value="command_line.html">Rails Command Line Tools and Rake Tasks</option>
130
+ <option value="asset_pipeline.html">Asset Pipeline</option>
131
+ <option value="working_with_javascript_in_rails.html">Working with JavaScript in Rails</option>
132
+ </optgroup>
133
+ <optgroup label="Extending Rails">
134
+ <option value="rails_on_rack.html">Rails on Rack</option>
135
+ <option value="generators.html">Creating and Customizing Rails Generators</option>
136
+ </optgroup>
137
+ <optgroup label="Contributing to Ruby on Rails">
138
+ <option value="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</option>
139
+ <option value="api_documentation_guidelines.html">API Documentation Guidelines</option>
140
+ <option value="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</option>
141
+ </optgroup>
142
+ <optgroup label="Maintenance Policy">
143
+ <option value="maintenance_policy.html">Maintenance Policy</option>
144
+ </optgroup>
145
+ <optgroup label="Release Notes">
146
+ <option value="upgrading_ruby_on_rails.html">Upgrading Ruby on Rails</option>
147
+ <option value="4_1_release_notes.html">Ruby on Rails 4.1 Release Notes</option>
148
+ <option value="4_0_release_notes.html">Ruby on Rails 4.0 Release Notes</option>
149
+ <option value="3_2_release_notes.html">Ruby on Rails 3.2 Release Notes</option>
150
+ <option value="3_1_release_notes.html">Ruby on Rails 3.1 Release Notes</option>
151
+ <option value="3_0_release_notes.html">Ruby on Rails 3.0 Release Notes</option>
152
+ <option value="2_3_release_notes.html">Ruby on Rails 2.3 Release Notes</option>
153
+ <option value="2_2_release_notes.html">Ruby on Rails 2.2 Release Notes</option>
154
+ </optgroup>
155
+ </select>
156
+ </li>
157
+ </ul>
158
+ </div>
159
+ </div>
160
+ <hr class="hide" />
161
+
162
+ <div id="feature">
163
+ <div class="wrapper">
164
+ <h2>Getting Started with Engines</h2><p>In this guide you will learn about engines and how they can be used to provide
165
+ additional functionality to their host applications through a clean and very
166
+ easy-to-use interface.</p><p>After reading this guide, you will know:</p>
167
+ <ul>
168
+ <li>What makes an engine.</li>
169
+ <li>How to generate an engine.</li>
170
+ <li>Building features for the engine.</li>
171
+ <li>Hooking the engine into an application.</li>
172
+ <li>Overriding engine functionality in the application.</li>
173
+ </ul>
174
+
175
+
176
+ <div id="subCol">
177
+ <h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
178
+ <ol class="chapters">
179
+ <li><a href="#what-are-engines-questionmark">What are engines?</a></li>
180
+ <li>
181
+ <a href="#generating-an-engine">Generating an engine</a>
182
+
183
+ <ul>
184
+ <li><a href="#inside-an-engine">Inside an Engine</a></li>
185
+ </ul>
186
+ </li>
187
+ <li>
188
+ <a href="#providing-engine-functionality">Providing engine functionality</a>
189
+
190
+ <ul>
191
+ <li><a href="#generating-an-article-resource">Generating an Article Resource</a></li>
192
+ <li><a href="#generating-a-comments-resource">Generating a Comments Resource</a></li>
193
+ </ul>
194
+ </li>
195
+ <li>
196
+ <a href="#hooking-into-an-application">Hooking Into an Application</a>
197
+
198
+ <ul>
199
+ <li><a href="#mounting-the-engine">Mounting the Engine</a></li>
200
+ <li><a href="#engine-setup">Engine setup</a></li>
201
+ <li><a href="#using-a-class-provided-by-the-application">Using a Class Provided by the Application</a></li>
202
+ <li><a href="#configuring-an-engine">Configuring an Engine</a></li>
203
+ </ul>
204
+ </li>
205
+ <li>
206
+ <a href="#testing-an-engine">Testing an engine</a>
207
+
208
+ <ul>
209
+ <li><a href="#functional-tests">Functional Tests</a></li>
210
+ </ul>
211
+ </li>
212
+ <li>
213
+ <a href="#improving-engine-functionality">Improving engine functionality</a>
214
+
215
+ <ul>
216
+ <li><a href="#overriding-models-and-controllers">Overriding Models and Controllers</a></li>
217
+ <li><a href="#overriding-views">Overriding Views</a></li>
218
+ <li><a href="#routes">Routes</a></li>
219
+ <li><a href="#assets">Assets</a></li>
220
+ <li><a href="#separate-assets-&amp;-precompiling">Separate Assets &amp; Precompiling</a></li>
221
+ <li><a href="#other-gem-dependencies">Other Gem Dependencies</a></li>
222
+ </ul>
223
+ </li>
224
+ </ol>
225
+
226
+ </div>
227
+
228
+ </div>
229
+ </div>
230
+
231
+ <div id="container">
232
+ <div class="wrapper">
233
+ <div id="mainCol">
234
+ <h3 id="what-are-engines-questionmark">1 What are engines?</h3><p>Engines can be considered miniature applications that provide functionality to
235
+ their host applications. A Rails application is actually just a "supercharged"
236
+ engine, with the <code>Rails::Application</code> class inheriting a lot of its behavior
237
+ from <code>Rails::Engine</code>.</p><p>Therefore, engines and applications can be thought of almost the same thing,
238
+ just with subtle differences, as you'll see throughout this guide. Engines and
239
+ applications also share a common structure.</p><p>Engines are also closely related to plugins. The two share a common <code>lib</code>
240
+ directory structure, and are both generated using the <code>rails plugin new</code>
241
+ generator. The difference is that an engine is considered a "full plugin" by
242
+ Rails (as indicated by the <code>--full</code> option that's passed to the generator
243
+ command). We'll actually be using the <code>--mountable</code> option here, which includes
244
+ all the features of <code>--full</code>, and then some. This guide will refer to these
245
+ "full plugins" simply as "engines" throughout. An engine <strong>can</strong> be a plugin,
246
+ and a plugin <strong>can</strong> be an engine.</p><p>The engine that will be created in this guide will be called "blorgh". This
247
+ engine will provide blogging functionality to its host applications, allowing
248
+ for new articles and comments to be created. At the beginning of this guide, you
249
+ will be working solely within the engine itself, but in later sections you'll
250
+ see how to hook it into an application.</p><p>Engines can also be isolated from their host applications. This means that an
251
+ application is able to have a path provided by a routing helper such as
252
+ <code>articles_path</code> and use an engine also that provides a path also called
253
+ <code>articles_path</code>, and the two would not clash. Along with this, controllers, models
254
+ and table names are also namespaced. You'll see how to do this later in this
255
+ guide.</p><p>It's important to keep in mind at all times that the application should
256
+ <strong>always</strong> take precedence over its engines. An application is the object that
257
+ has final say in what goes on in its environment. The engine should
258
+ only be enhancing it, rather than changing it drastically.</p><p>To see demonstrations of other engines, check out
259
+ <a href="https://github.com/plataformatec/devise">Devise</a>, an engine that provides
260
+ authentication for its parent applications, or
261
+ <a href="https://github.com/radar/forem">Forem</a>, an engine that provides forum
262
+ functionality. There's also <a href="https://github.com/spree/spree">Spree</a> which
263
+ provides an e-commerce platform, and
264
+ <a href="https://github.com/refinery/refinerycms">RefineryCMS</a>, a CMS engine.</p><p>Finally, engines would not have been possible without the work of James Adam,
265
+ Piotr Sarnacki, the Rails Core Team, and a number of other people. If you ever
266
+ meet them, don't forget to say thanks!</p><h3 id="generating-an-engine">2 Generating an engine</h3><p>To generate an engine, you will need to run the plugin generator and pass it
267
+ options as appropriate to the need. For the "blorgh" example, you will need to
268
+ create a "mountable" engine, running this command in a terminal:</p><div class="code_container">
269
+ <pre class="brush: plain; gutter: false; toolbar: false">
270
+ $ bin/rails plugin new blorgh --mountable
271
+
272
+ </pre>
273
+ </div>
274
+ <p>The full list of options for the plugin generator may be seen by typing:</p><div class="code_container">
275
+ <pre class="brush: plain; gutter: false; toolbar: false">
276
+ $ bin/rails plugin --help
277
+
278
+ </pre>
279
+ </div>
280
+ <p>The <code>--mountable</code> option tells the generator that you want to create a
281
+ "mountable" and namespace-isolated engine. This generator will provide the same
282
+ skeleton structure as would the <code>--full</code> option. The <code>--full</code> option tells the
283
+ generator that you want to create an engine, including a skeleton structure
284
+ that provides the following:</p>
285
+ <ul>
286
+ <li>An <code>app</code> directory tree</li>
287
+ <li>
288
+ <p>A <code>config/routes.rb</code> file:</p>
289
+ <div class="code_container">
290
+ <pre class="brush: ruby; gutter: false; toolbar: false">
291
+ Rails.application.routes.draw do
292
+ end
293
+
294
+ </pre>
295
+ </div>
296
+ </li>
297
+ <li>
298
+ <p>A file at <code>lib/blorgh/engine.rb</code>, which is identical in function to a
299
+ standard Rails application's <code>config/application.rb</code> file:</p>
300
+ <div class="code_container">
301
+ <pre class="brush: ruby; gutter: false; toolbar: false">
302
+ module Blorgh
303
+ class Engine &lt; ::Rails::Engine
304
+ end
305
+ end
306
+
307
+ </pre>
308
+ </div>
309
+ </li>
310
+ </ul>
311
+ <p>The <code>--mountable</code> option will add to the <code>--full</code> option:</p>
312
+ <ul>
313
+ <li>Asset manifest files (<code>application.js</code> and <code>application.css</code>)</li>
314
+ <li>A namespaced <code>ApplicationController</code> stub</li>
315
+ <li>A namespaced <code>ApplicationHelper</code> stub</li>
316
+ <li>A layout view template for the engine</li>
317
+ <li>
318
+ <p>Namespace isolation to <code>config/routes.rb</code>:</p>
319
+ <div class="code_container">
320
+ <pre class="brush: ruby; gutter: false; toolbar: false">
321
+ Blorgh::Engine.routes.draw do
322
+ end
323
+
324
+ </pre>
325
+ </div>
326
+ </li>
327
+ <li>
328
+ <p>Namespace isolation to <code>lib/blorgh/engine.rb</code>:</p>
329
+ <div class="code_container">
330
+ <pre class="brush: ruby; gutter: false; toolbar: false">
331
+ module Blorgh
332
+ class Engine &lt; ::Rails::Engine
333
+ isolate_namespace Blorgh
334
+ end
335
+ end
336
+
337
+ </pre>
338
+ </div>
339
+ </li>
340
+ </ul>
341
+ <p>Additionally, the <code>--mountable</code> option tells the generator to mount the engine
342
+ inside the dummy testing application located at <code>test/dummy</code> by adding the
343
+ following to the dummy application's routes file at
344
+ <code>test/dummy/config/routes.rb</code>:</p><div class="code_container">
345
+ <pre class="brush: ruby; gutter: false; toolbar: false">
346
+ mount Blorgh::Engine =&gt; "/blorgh"
347
+
348
+ </pre>
349
+ </div>
350
+ <h4 id="inside-an-engine">2.1 Inside an Engine</h4><h5 id="critical-files">2.1.1 Critical Files</h5><p>At the root of this brand new engine's directory lives a <code>blorgh.gemspec</code> file.
351
+ When you include the engine into an application later on, you will do so with
352
+ this line in the Rails application's <code>Gemfile</code>:</p><div class="code_container">
353
+ <pre class="brush: ruby; gutter: false; toolbar: false">
354
+ gem 'blorgh', path: "vendor/engines/blorgh"
355
+
356
+ </pre>
357
+ </div>
358
+ <p>Don't forget to run <code>bundle install</code> as usual. By specifying it as a gem within
359
+ the <code>Gemfile</code>, Bundler will load it as such, parsing this <code>blorgh.gemspec</code> file
360
+ and requiring a file within the <code>lib</code> directory called <code>lib/blorgh.rb</code>. This
361
+ file requires the <code>blorgh/engine.rb</code> file (located at <code>lib/blorgh/engine.rb</code>)
362
+ and defines a base module called <code>Blorgh</code>.</p><div class="code_container">
363
+ <pre class="brush: ruby; gutter: false; toolbar: false">
364
+ require "blorgh/engine"
365
+
366
+ module Blorgh
367
+ end
368
+
369
+ </pre>
370
+ </div>
371
+ <div class="info"><p>Some engines choose to use this file to put global configuration options
372
+ for their engine. It's a relatively good idea, so if you want to offer
373
+ configuration options, the file where your engine's <code>module</code> is defined is
374
+ perfect for that. Place the methods inside the module and you'll be good to go.</p></div><p>Within <code>lib/blorgh/engine.rb</code> is the base class for the engine:</p><div class="code_container">
375
+ <pre class="brush: ruby; gutter: false; toolbar: false">
376
+ module Blorgh
377
+ class Engine &lt; ::Rails::Engine
378
+ isolate_namespace Blorgh
379
+ end
380
+ end
381
+
382
+ </pre>
383
+ </div>
384
+ <p>By inheriting from the <code>Rails::Engine</code> class, this gem notifies Rails that
385
+ there's an engine at the specified path, and will correctly mount the engine
386
+ inside the application, performing tasks such as adding the <code>app</code> directory of
387
+ the engine to the load path for models, mailers, controllers and views.</p><p>The <code>isolate_namespace</code> method here deserves special notice. This call is
388
+ responsible for isolating the controllers, models, routes and other things into
389
+ their own namespace, away from similar components inside the application.
390
+ Without this, there is a possibility that the engine's components could "leak"
391
+ into the application, causing unwanted disruption, or that important engine
392
+ components could be overridden by similarly named things within the application.
393
+ One of the examples of such conflicts is helpers. Without calling
394
+ <code>isolate_namespace</code>, the engine's helpers would be included in an application's
395
+ controllers.</p><div class="note"><p>It is <strong>highly</strong> recommended that the <code>isolate_namespace</code> line be left
396
+ within the <code>Engine</code> class definition. Without it, classes generated in an engine
397
+ <strong>may</strong> conflict with an application.</p></div><p>What this isolation of the namespace means is that a model generated by a call
398
+ to <code>bin/rails g model</code>, such as <code>bin/rails g model article</code>, won't be called <code>Article</code>, but
399
+ instead be namespaced and called <code>Blorgh::Article</code>. In addition, the table for the
400
+ model is namespaced, becoming <code>blorgh_articles</code>, rather than simply <code>articles</code>.
401
+ Similar to the model namespacing, a controller called <code>ArticlesController</code> becomes
402
+ <code>Blorgh::ArticlesController</code> and the views for that controller will not be at
403
+ <code>app/views/articles</code>, but <code>app/views/blorgh/articles</code> instead. Mailers are namespaced
404
+ as well.</p><p>Finally, routes will also be isolated within the engine. This is one of the most
405
+ important parts about namespacing, and is discussed later in the
406
+ <a href="#routes">Routes</a> section of this guide.</p><h5 id="app-directory">2.1.2 <code>app</code> Directory</h5><p>Inside the <code>app</code> directory are the standard <code>assets</code>, <code>controllers</code>, <code>helpers</code>,
407
+ <code>mailers</code>, <code>models</code> and <code>views</code> directories that you should be familiar with
408
+ from an application. The <code>helpers</code>, <code>mailers</code> and <code>models</code> directories are
409
+ empty, so they aren't described in this section. We'll look more into models in
410
+ a future section, when we're writing the engine.</p><p>Within the <code>app/assets</code> directory, there are the <code>images</code>, <code>javascripts</code> and
411
+ <code>stylesheets</code> directories which, again, you should be familiar with due to their
412
+ similarity to an application. One difference here, however, is that each
413
+ directory contains a sub-directory with the engine name. Because this engine is
414
+ going to be namespaced, its assets should be too.</p><p>Within the <code>app/controllers</code> directory there is a <code>blorgh</code> directory that
415
+ contains a file called <code>application_controller.rb</code>. This file will provide any
416
+ common functionality for the controllers of the engine. The <code>blorgh</code> directory
417
+ is where the other controllers for the engine will go. By placing them within
418
+ this namespaced directory, you prevent them from possibly clashing with
419
+ identically-named controllers within other engines or even within the
420
+ application.</p><div class="note"><p>The <code>ApplicationController</code> class inside an engine is named just like a
421
+ Rails application in order to make it easier for you to convert your
422
+ applications into engines.</p></div><p>Lastly, the <code>app/views</code> directory contains a <code>layouts</code> folder, which contains a
423
+ file at <code>blorgh/application.html.erb</code>. This file allows you to specify a layout
424
+ for the engine. If this engine is to be used as a stand-alone engine, then you
425
+ would add any customization to its layout in this file, rather than the
426
+ application's <code>app/views/layouts/application.html.erb</code> file.</p><p>If you don't want to force a layout on to users of the engine, then you can
427
+ delete this file and reference a different layout in the controllers of your
428
+ engine.</p><h5 id="bin-directory">2.1.3 <code>bin</code> Directory</h5><p>This directory contains one file, <code>bin/rails</code>, which enables you to use the
429
+ <code>rails</code> sub-commands and generators just like you would within an application.
430
+ This means that you will be able to generate new controllers and models for this
431
+ engine very easily by running commands like this:</p><div class="code_container">
432
+ <pre class="brush: plain; gutter: false; toolbar: false">
433
+ $ bin/rails g model
434
+
435
+ </pre>
436
+ </div>
437
+ <p>Keep in mind, of course, that anything generated with these commands inside of
438
+ an engine that has <code>isolate_namespace</code> in the <code>Engine</code> class will be namespaced.</p><h5 id="test-directory">2.1.4 <code>test</code> Directory</h5><p>The <code>test</code> directory is where tests for the engine will go. To test the engine,
439
+ there is a cut-down version of a Rails application embedded within it at
440
+ <code>test/dummy</code>. This application will mount the engine in the
441
+ <code>test/dummy/config/routes.rb</code> file:</p><div class="code_container">
442
+ <pre class="brush: ruby; gutter: false; toolbar: false">
443
+ Rails.application.routes.draw do
444
+ mount Blorgh::Engine =&gt; "/blorgh"
445
+ end
446
+
447
+ </pre>
448
+ </div>
449
+ <p>This line mounts the engine at the path <code>/blorgh</code>, which will make it accessible
450
+ through the application only at that path.</p><p>Inside the test directory there is the <code>test/integration</code> directory, where
451
+ integration tests for the engine should be placed. Other directories can be
452
+ created in the <code>test</code> directory as well. For example, you may wish to create a
453
+ <code>test/models</code> directory for your model tests.</p><h3 id="providing-engine-functionality">3 Providing engine functionality</h3><p>The engine that this guide covers provides submitting articles and commenting
454
+ functionality and follows a similar thread to the <a href="getting_started.html">Getting Started
455
+ Guide</a>, with some new twists.</p><h4 id="generating-an-article-resource">3.1 Generating an Article Resource</h4><p>The first thing to generate for a blog engine is the <code>Article</code> model and related
456
+ controller. To quickly generate this, you can use the Rails scaffold generator.</p><div class="code_container">
457
+ <pre class="brush: plain; gutter: false; toolbar: false">
458
+ $ bin/rails generate scaffold article title:string text:text
459
+
460
+ </pre>
461
+ </div>
462
+ <p>This command will output this information:</p><div class="code_container">
463
+ <pre class="brush: plain; gutter: false; toolbar: false">
464
+ invoke active_record
465
+ create db/migrate/[timestamp]_create_blorgh_articles.rb
466
+ create app/models/blorgh/article.rb
467
+ invoke test_unit
468
+ create test/models/blorgh/article_test.rb
469
+ create test/fixtures/blorgh/articles.yml
470
+ invoke resource_route
471
+ route resources :articles
472
+ invoke scaffold_controller
473
+ create app/controllers/blorgh/articles_controller.rb
474
+ invoke erb
475
+ create app/views/blorgh/articles
476
+ create app/views/blorgh/articles/index.html.erb
477
+ create app/views/blorgh/articles/edit.html.erb
478
+ create app/views/blorgh/articles/show.html.erb
479
+ create app/views/blorgh/articles/new.html.erb
480
+ create app/views/blorgh/articles/_form.html.erb
481
+ invoke test_unit
482
+ create test/controllers/blorgh/articles_controller_test.rb
483
+ invoke helper
484
+ create app/helpers/blorgh/articles_helper.rb
485
+ invoke assets
486
+ invoke js
487
+ create app/assets/javascripts/blorgh/articles.js
488
+ invoke css
489
+ create app/assets/stylesheets/blorgh/articles.css
490
+ invoke css
491
+ create app/assets/stylesheets/scaffold.css
492
+
493
+ </pre>
494
+ </div>
495
+ <p>The first thing that the scaffold generator does is invoke the <code>active_record</code>
496
+ generator, which generates a migration and a model for the resource. Note here,
497
+ however, that the migration is called <code>create_blorgh_articles</code> rather than the
498
+ usual <code>create_articles</code>. This is due to the <code>isolate_namespace</code> method called in
499
+ the <code>Blorgh::Engine</code> class's definition. The model here is also namespaced,
500
+ being placed at <code>app/models/blorgh/article.rb</code> rather than <code>app/models/article.rb</code> due
501
+ to the <code>isolate_namespace</code> call within the <code>Engine</code> class.</p><p>Next, the <code>test_unit</code> generator is invoked for this model, generating a model
502
+ test at <code>test/models/blorgh/article_test.rb</code> (rather than
503
+ <code>test/models/article_test.rb</code>) and a fixture at <code>test/fixtures/blorgh/articles.yml</code>
504
+ (rather than <code>test/fixtures/articles.yml</code>).</p><p>After that, a line for the resource is inserted into the <code>config/routes.rb</code> file
505
+ for the engine. This line is simply <code>resources :articles</code>, turning the
506
+ <code>config/routes.rb</code> file for the engine into this:</p><div class="code_container">
507
+ <pre class="brush: ruby; gutter: false; toolbar: false">
508
+ Blorgh::Engine.routes.draw do
509
+ resources :articles
510
+ end
511
+
512
+ </pre>
513
+ </div>
514
+ <p>Note here that the routes are drawn upon the <code>Blorgh::Engine</code> object rather than
515
+ the <code>YourApp::Application</code> class. This is so that the engine routes are confined
516
+ to the engine itself and can be mounted at a specific point as shown in the
517
+ <a href="#test-directory">test directory</a> section. It also causes the engine's routes to
518
+ be isolated from those routes that are within the application. The
519
+ <a href="#routes">Routes</a> section of this guide describes it in detail.</p><p>Next, the <code>scaffold_controller</code> generator is invoked, generating a controller
520
+ called <code>Blorgh::ArticlesController</code> (at
521
+ <code>app/controllers/blorgh/articles_controller.rb</code>) and its related views at
522
+ <code>app/views/blorgh/articles</code>. This generator also generates a test for the
523
+ controller (<code>test/controllers/blorgh/articles_controller_test.rb</code>) and a helper
524
+ (<code>app/helpers/blorgh/articles_controller.rb</code>).</p><p>Everything this generator has created is neatly namespaced. The controller's
525
+ class is defined within the <code>Blorgh</code> module:</p><div class="code_container">
526
+ <pre class="brush: ruby; gutter: false; toolbar: false">
527
+ module Blorgh
528
+ class ArticlesController &lt; ApplicationController
529
+ ...
530
+ end
531
+ end
532
+
533
+ </pre>
534
+ </div>
535
+ <div class="note"><p>The <code>ApplicationController</code> class being inherited from here is the
536
+ <code>Blorgh::ApplicationController</code>, not an application's <code>ApplicationController</code>.</p></div><p>The helper inside <code>app/helpers/blorgh/articles_helper.rb</code> is also namespaced:</p><div class="code_container">
537
+ <pre class="brush: ruby; gutter: false; toolbar: false">
538
+ module Blorgh
539
+ module ArticlesHelper
540
+ ...
541
+ end
542
+ end
543
+
544
+ </pre>
545
+ </div>
546
+ <p>This helps prevent conflicts with any other engine or application that may have
547
+ an article resource as well.</p><p>Finally, the assets for this resource are generated in two files:
548
+ <code>app/assets/javascripts/blorgh/articles.js</code> and
549
+ <code>app/assets/stylesheets/blorgh/articles.css</code>. You'll see how to use these a little
550
+ later.</p><p>By default, the scaffold styling is not applied to the engine because the
551
+ engine's layout file, <code>app/views/layouts/blorgh/application.html.erb</code>, doesn't
552
+ load it. To make the scaffold styling apply, insert this line into the <code>&lt;head&gt;</code>
553
+ tag of this layout:</p><div class="code_container">
554
+ <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
555
+ &lt;%= stylesheet_link_tag "scaffold" %&gt;
556
+
557
+ </pre>
558
+ </div>
559
+ <p>You can see what the engine has so far by running <code>rake db:migrate</code> at the root
560
+ of our engine to run the migration generated by the scaffold generator, and then
561
+ running <code>rails server</code> in <code>test/dummy</code>. When you open
562
+ <code>http://localhost:3000/blorgh/articles</code> you will see the default scaffold that has
563
+ been generated. Click around! You've just generated your first engine's first
564
+ functions.</p><p>If you'd rather play around in the console, <code>rails console</code> will also work just
565
+ like a Rails application. Remember: the <code>Article</code> model is namespaced, so to
566
+ reference it you must call it as <code>Blorgh::Article</code>.</p><div class="code_container">
567
+ <pre class="brush: ruby; gutter: false; toolbar: false">
568
+ &gt;&gt; Blorgh::Article.find(1)
569
+ =&gt; #&lt;Blorgh::Article id: 1 ...&gt;
570
+
571
+ </pre>
572
+ </div>
573
+ <p>One final thing is that the <code>articles</code> resource for this engine should be the root
574
+ of the engine. Whenever someone goes to the root path where the engine is
575
+ mounted, they should be shown a list of articles. This can be made to happen if
576
+ this line is inserted into the <code>config/routes.rb</code> file inside the engine:</p><div class="code_container">
577
+ <pre class="brush: ruby; gutter: false; toolbar: false">
578
+ root to: "articles#index"
579
+
580
+ </pre>
581
+ </div>
582
+ <p>Now people will only need to go to the root of the engine to see all the articles,
583
+ rather than visiting <code>/articles</code>. This means that instead of
584
+ <code>http://localhost:3000/blorgh/articles</code>, you only need to go to
585
+ <code>http://localhost:3000/blorgh</code> now.</p><h4 id="generating-a-comments-resource">3.2 Generating a Comments Resource</h4><p>Now that the engine can create new articles, it only makes sense to add
586
+ commenting functionality as well. To do this, you'll need to generate a comment
587
+ model, a comment controller and then modify the articles scaffold to display
588
+ comments and allow people to create new ones.</p><p>From the application root, run the model generator. Tell it to generate a
589
+ <code>Comment</code> model, with the related table having two columns: a <code>article_id</code> integer
590
+ and <code>text</code> text column.</p><div class="code_container">
591
+ <pre class="brush: plain; gutter: false; toolbar: false">
592
+ $ bin/rails generate model Comment article_id:integer text:text
593
+
594
+ </pre>
595
+ </div>
596
+ <p>This will output the following:</p><div class="code_container">
597
+ <pre class="brush: plain; gutter: false; toolbar: false">
598
+ invoke active_record
599
+ create db/migrate/[timestamp]_create_blorgh_comments.rb
600
+ create app/models/blorgh/comment.rb
601
+ invoke test_unit
602
+ create test/models/blorgh/comment_test.rb
603
+ create test/fixtures/blorgh/comments.yml
604
+
605
+ </pre>
606
+ </div>
607
+ <p>This generator call will generate just the necessary model files it needs,
608
+ namespacing the files under a <code>blorgh</code> directory and creating a model class
609
+ called <code>Blorgh::Comment</code>. Now run the migration to create our blorgh_comments
610
+ table:</p><div class="code_container">
611
+ <pre class="brush: plain; gutter: false; toolbar: false">
612
+ $ rake db:migrate
613
+
614
+ </pre>
615
+ </div>
616
+ <p>To show the comments on an article, edit <code>app/views/blorgh/articles/show.html.erb</code> and
617
+ add this line before the "Edit" link:</p><div class="code_container">
618
+ <pre class="brush: plain; gutter: false; toolbar: false">
619
+ &lt;h3&gt;Comments&lt;/h3&gt;
620
+ &lt;%= render @article.comments %&gt;
621
+
622
+ </pre>
623
+ </div>
624
+ <p>This line will require there to be a <code>has_many</code> association for comments defined
625
+ on the <code>Blorgh::Article</code> model, which there isn't right now. To define one, open
626
+ <code>app/models/blorgh/article.rb</code> and add this line into the model:</p><div class="code_container">
627
+ <pre class="brush: ruby; gutter: false; toolbar: false">
628
+ has_many :comments
629
+
630
+ </pre>
631
+ </div>
632
+ <p>Turning the model into this:</p><div class="code_container">
633
+ <pre class="brush: ruby; gutter: false; toolbar: false">
634
+ module Blorgh
635
+ class Article &lt; ActiveRecord::Base
636
+ has_many :comments
637
+ end
638
+ end
639
+
640
+ </pre>
641
+ </div>
642
+ <div class="note"><p>Because the <code>has_many</code> is defined inside a class that is inside the
643
+ <code>Blorgh</code> module, Rails will know that you want to use the <code>Blorgh::Comment</code>
644
+ model for these objects, so there's no need to specify that using the
645
+ <code>:class_name</code> option here.</p></div><p>Next, there needs to be a form so that comments can be created on an article. To
646
+ add this, put this line underneath the call to <code>render @article.comments</code> in
647
+ <code>app/views/blorgh/articles/show.html.erb</code>:</p><div class="code_container">
648
+ <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
649
+ &lt;%= render "blorgh/comments/form" %&gt;
650
+
651
+ </pre>
652
+ </div>
653
+ <p>Next, the partial that this line will render needs to exist. Create a new
654
+ directory at <code>app/views/blorgh/comments</code> and in it a new file called
655
+ <code>_form.html.erb</code> which has this content to create the required partial:</p><div class="code_container">
656
+ <pre class="brush: plain; gutter: false; toolbar: false">
657
+ &lt;h3&gt;New comment&lt;/h3&gt;
658
+ &lt;%= form_for [@article, @article.comments.build] do |f| %&gt;
659
+ &lt;p&gt;
660
+ &lt;%= f.label :text %&gt;&lt;br&gt;
661
+ &lt;%= f.text_area :text %&gt;
662
+ &lt;/p&gt;
663
+ &lt;%= f.submit %&gt;
664
+ &lt;% end %&gt;
665
+
666
+ </pre>
667
+ </div>
668
+ <p>When this form is submitted, it is going to attempt to perform a <code>POST</code> request
669
+ to a route of <code>/articles/:article_id/comments</code> within the engine. This route doesn't
670
+ exist at the moment, but can be created by changing the <code>resources :articles</code> line
671
+ inside <code>config/routes.rb</code> into these lines:</p><div class="code_container">
672
+ <pre class="brush: ruby; gutter: false; toolbar: false">
673
+ resources :articles do
674
+ resources :comments
675
+ end
676
+
677
+ </pre>
678
+ </div>
679
+ <p>This creates a nested route for the comments, which is what the form requires.</p><p>The route now exists, but the controller that this route goes to does not. To
680
+ create it, run this command from the application root:</p><div class="code_container">
681
+ <pre class="brush: plain; gutter: false; toolbar: false">
682
+ $ bin/rails g controller comments
683
+
684
+ </pre>
685
+ </div>
686
+ <p>This will generate the following things:</p><div class="code_container">
687
+ <pre class="brush: plain; gutter: false; toolbar: false">
688
+ create app/controllers/blorgh/comments_controller.rb
689
+ invoke erb
690
+ exist app/views/blorgh/comments
691
+ invoke test_unit
692
+ create test/controllers/blorgh/comments_controller_test.rb
693
+ invoke helper
694
+ create app/helpers/blorgh/comments_helper.rb
695
+ invoke assets
696
+ invoke js
697
+ create app/assets/javascripts/blorgh/comments.js
698
+ invoke css
699
+ create app/assets/stylesheets/blorgh/comments.css
700
+
701
+ </pre>
702
+ </div>
703
+ <p>The form will be making a <code>POST</code> request to <code>/articles/:article_id/comments</code>, which
704
+ will correspond with the <code>create</code> action in <code>Blorgh::CommentsController</code>. This
705
+ action needs to be created, which can be done by putting the following lines
706
+ inside the class definition in <code>app/controllers/blorgh/comments_controller.rb</code>:</p><div class="code_container">
707
+ <pre class="brush: ruby; gutter: false; toolbar: false">
708
+ def create
709
+ @article = Article.find(params[:article_id])
710
+ @comment = @article.comments.create(comment_params)
711
+ flash[:notice] = "Comment has been created!"
712
+ redirect_to articles_path
713
+ end
714
+
715
+ private
716
+ def comment_params
717
+ params.require(:comment).permit(:text)
718
+ end
719
+
720
+ </pre>
721
+ </div>
722
+ <p>This is the final step required to get the new comment form working. Displaying
723
+ the comments, however, is not quite right yet. If you were to create a comment
724
+ right now, you would see this error:</p><div class="code_container">
725
+ <pre class="brush: plain; gutter: false; toolbar: false">
726
+ Missing partial blorgh/comments/comment with {:handlers=&gt;[:erb, :builder],
727
+ :formats=&gt;[:html], :locale=&gt;[:en, :en]}. Searched in: *
728
+ "/Users/ryan/Sites/side_projects/blorgh/test/dummy/app/views" *
729
+ "/Users/ryan/Sites/side_projects/blorgh/app/views"
730
+
731
+ </pre>
732
+ </div>
733
+ <p>The engine is unable to find the partial required for rendering the comments.
734
+ Rails looks first in the application's (<code>test/dummy</code>) <code>app/views</code> directory and
735
+ then in the engine's <code>app/views</code> directory. When it can't find it, it will throw
736
+ this error. The engine knows to look for <code>blorgh/comments/comment</code> because the
737
+ model object it is receiving is from the <code>Blorgh::Comment</code> class.</p><p>This partial will be responsible for rendering just the comment text, for now.
738
+ Create a new file at <code>app/views/blorgh/comments/_comment.html.erb</code> and put this
739
+ line inside it:</p><div class="code_container">
740
+ <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
741
+ &lt;%= comment_counter + 1 %&gt;. &lt;%= comment.text %&gt;
742
+
743
+ </pre>
744
+ </div>
745
+ <p>The <code>comment_counter</code> local variable is given to us by the <code>&lt;%= render
746
+ @article.comments %&gt;</code> call, which will define it automatically and increment the
747
+ counter as it iterates through each comment. It's used in this example to
748
+ display a small number next to each comment when it's created.</p><p>That completes the comment function of the blogging engine. Now it's time to use
749
+ it within an application.</p><h3 id="hooking-into-an-application">4 Hooking Into an Application</h3><p>Using an engine within an application is very easy. This section covers how to
750
+ mount the engine into an application and the initial setup required, as well as
751
+ linking the engine to a <code>User</code> class provided by the application to provide
752
+ ownership for articles and comments within the engine.</p><h4 id="mounting-the-engine">4.1 Mounting the Engine</h4><p>First, the engine needs to be specified inside the application's <code>Gemfile</code>. If
753
+ there isn't an application handy to test this out in, generate one using the
754
+ <code>rails new</code> command outside of the engine directory like this:</p><div class="code_container">
755
+ <pre class="brush: plain; gutter: false; toolbar: false">
756
+ $ rails new unicorn
757
+
758
+ </pre>
759
+ </div>
760
+ <p>Usually, specifying the engine inside the Gemfile would be done by specifying it
761
+ as a normal, everyday gem.</p><div class="code_container">
762
+ <pre class="brush: ruby; gutter: false; toolbar: false">
763
+ gem 'devise'
764
+
765
+ </pre>
766
+ </div>
767
+ <p>However, because you are developing the <code>blorgh</code> engine on your local machine,
768
+ you will need to specify the <code>:path</code> option in your <code>Gemfile</code>:</p><div class="code_container">
769
+ <pre class="brush: ruby; gutter: false; toolbar: false">
770
+ gem 'blorgh', path: "/path/to/blorgh"
771
+
772
+ </pre>
773
+ </div>
774
+ <p>Then run <code>bundle</code> to install the gem.</p><p>As described earlier, by placing the gem in the <code>Gemfile</code> it will be loaded when
775
+ Rails is loaded. It will first require <code>lib/blorgh.rb</code> from the engine, then
776
+ <code>lib/blorgh/engine.rb</code>, which is the file that defines the major pieces of
777
+ functionality for the engine.</p><p>To make the engine's functionality accessible from within an application, it
778
+ needs to be mounted in that application's <code>config/routes.rb</code> file:</p><div class="code_container">
779
+ <pre class="brush: ruby; gutter: false; toolbar: false">
780
+ mount Blorgh::Engine, at: "/blog"
781
+
782
+ </pre>
783
+ </div>
784
+ <p>This line will mount the engine at <code>/blog</code> in the application. Making it
785
+ accessible at <code>http://localhost:3000/blog</code> when the application runs with <code>rails
786
+ server</code>.</p><div class="note"><p>Other engines, such as Devise, handle this a little differently by making
787
+ you specify custom helpers (such as <code>devise_for</code>) in the routes. These helpers
788
+ do exactly the same thing, mounting pieces of the engines's functionality at a
789
+ pre-defined path which may be customizable.</p></div><h4 id="engine-setup">4.2 Engine setup</h4><p>The engine contains migrations for the <code>blorgh_articles</code> and <code>blorgh_comments</code>
790
+ table which need to be created in the application's database so that the
791
+ engine's models can query them correctly. To copy these migrations into the
792
+ application use this command:</p><div class="code_container">
793
+ <pre class="brush: plain; gutter: false; toolbar: false">
794
+ $ rake blorgh:install:migrations
795
+
796
+ </pre>
797
+ </div>
798
+ <p>If you have multiple engines that need migrations copied over, use
799
+ <code>railties:install:migrations</code> instead:</p><div class="code_container">
800
+ <pre class="brush: plain; gutter: false; toolbar: false">
801
+ $ rake railties:install:migrations
802
+
803
+ </pre>
804
+ </div>
805
+ <p>This command, when run for the first time, will copy over all the migrations
806
+ from the engine. When run the next time, it will only copy over migrations that
807
+ haven't been copied over already. The first run for this command will output
808
+ something such as this:</p><div class="code_container">
809
+ <pre class="brush: plain; gutter: false; toolbar: false">
810
+ Copied migration [timestamp_1]_create_blorgh_articles.rb from blorgh
811
+ Copied migration [timestamp_2]_create_blorgh_comments.rb from blorgh
812
+
813
+ </pre>
814
+ </div>
815
+ <p>The first timestamp (<code>[timestamp_1]</code>) will be the current time, and the second
816
+ timestamp (<code>[timestamp_2]</code>) will be the current time plus a second. The reason
817
+ for this is so that the migrations for the engine are run after any existing
818
+ migrations in the application.</p><p>To run these migrations within the context of the application, simply run <code>rake
819
+ db:migrate</code>. When accessing the engine through <code>http://localhost:3000/blog</code>, the
820
+ articles will be empty. This is because the table created inside the application is
821
+ different from the one created within the engine. Go ahead, play around with the
822
+ newly mounted engine. You'll find that it's the same as when it was only an
823
+ engine.</p><p>If you would like to run migrations only from one engine, you can do it by
824
+ specifying <code>SCOPE</code>:</p><div class="code_container">
825
+ <pre class="brush: plain; gutter: false; toolbar: false">
826
+ rake db:migrate SCOPE=blorgh
827
+
828
+ </pre>
829
+ </div>
830
+ <p>This may be useful if you want to revert engine's migrations before removing it.
831
+ To revert all migrations from blorgh engine you can run code such as:</p><div class="code_container">
832
+ <pre class="brush: plain; gutter: false; toolbar: false">
833
+ rake db:migrate SCOPE=blorgh VERSION=0
834
+
835
+ </pre>
836
+ </div>
837
+ <h4 id="using-a-class-provided-by-the-application">4.3 Using a Class Provided by the Application</h4><h5 id="using-a-model-provided-by-the-application">4.3.1 Using a Model Provided by the Application</h5><p>When an engine is created, it may want to use specific classes from an
838
+ application to provide links between the pieces of the engine and the pieces of
839
+ the application. In the case of the <code>blorgh</code> engine, making articles and comments
840
+ have authors would make a lot of sense.</p><p>A typical application might have a <code>User</code> class that would be used to represent
841
+ authors for an article or a comment. But there could be a case where the
842
+ application calls this class something different, such as <code>Person</code>. For this
843
+ reason, the engine should not hardcode associations specifically for a <code>User</code>
844
+ class.</p><p>To keep it simple in this case, the application will have a class called <code>User</code>
845
+ that represents the users of the application (we'll get into making this
846
+ configurable further on). It can be generated using this command inside the
847
+ application:</p><div class="code_container">
848
+ <pre class="brush: plain; gutter: false; toolbar: false">
849
+ rails g model user name:string
850
+
851
+ </pre>
852
+ </div>
853
+ <p>The <code>rake db:migrate</code> command needs to be run here to ensure that our
854
+ application has the <code>users</code> table for future use.</p><p>Also, to keep it simple, the articles form will have a new text field called
855
+ <code>author_name</code>, where users can elect to put their name. The engine will then
856
+ take this name and either create a new <code>User</code> object from it, or find one that
857
+ already has that name. The engine will then associate the article with the found or
858
+ created <code>User</code> object.</p><p>First, the <code>author_name</code> text field needs to be added to the
859
+ <code>app/views/blorgh/articles/_form.html.erb</code> partial inside the engine. This can be
860
+ added above the <code>title</code> field with this code:</p><div class="code_container">
861
+ <pre class="brush: plain; gutter: false; toolbar: false">
862
+ &lt;div class="field"&gt;
863
+ &lt;%= f.label :author_name %&gt;&lt;br&gt;
864
+ &lt;%= f.text_field :author_name %&gt;
865
+ &lt;/div&gt;
866
+
867
+ </pre>
868
+ </div>
869
+ <p>Next, we need to update our <code>Blorgh::ArticleController#article_params</code> method to
870
+ permit the new form parameter:</p><div class="code_container">
871
+ <pre class="brush: ruby; gutter: false; toolbar: false">
872
+ def article_params
873
+ params.require(:article).permit(:title, :text, :author_name)
874
+ end
875
+
876
+ </pre>
877
+ </div>
878
+ <p>The <code>Blorgh::Article</code> model should then have some code to convert the <code>author_name</code>
879
+ field into an actual <code>User</code> object and associate it as that article's <code>author</code>
880
+ before the article is saved. It will also need to have an <code>attr_accessor</code> set up
881
+ for this field, so that the setter and getter methods are defined for it.</p><p>To do all this, you'll need to add the <code>attr_accessor</code> for <code>author_name</code>, the
882
+ association for the author and the <code>before_save</code> call into
883
+ <code>app/models/blorgh/article.rb</code>. The <code>author</code> association will be hard-coded to the
884
+ <code>User</code> class for the time being.</p><div class="code_container">
885
+ <pre class="brush: ruby; gutter: false; toolbar: false">
886
+ attr_accessor :author_name
887
+ belongs_to :author, class_name: "User"
888
+
889
+ before_save :set_author
890
+
891
+ private
892
+ def set_author
893
+ self.author = User.find_or_create_by(name: author_name)
894
+ end
895
+
896
+ </pre>
897
+ </div>
898
+ <p>By representing the <code>author</code> association's object with the <code>User</code> class, a link
899
+ is established between the engine and the application. There needs to be a way
900
+ of associating the records in the <code>blorgh_articles</code> table with the records in the
901
+ <code>users</code> table. Because the association is called <code>author</code>, there should be an
902
+ <code>author_id</code> column added to the <code>blorgh_articles</code> table.</p><p>To generate this new column, run this command within the engine:</p><div class="code_container">
903
+ <pre class="brush: plain; gutter: false; toolbar: false">
904
+ $ bin/rails g migration add_author_id_to_blorgh_articles author_id:integer
905
+
906
+ </pre>
907
+ </div>
908
+ <div class="note"><p>Due to the migration's name and the column specification after it, Rails
909
+ will automatically know that you want to add a column to a specific table and
910
+ write that into the migration for you. You don't need to tell it any more than
911
+ this.</p></div><p>This migration will need to be run on the application. To do that, it must first
912
+ be copied using this command:</p><div class="code_container">
913
+ <pre class="brush: plain; gutter: false; toolbar: false">
914
+ $ rake blorgh:install:migrations
915
+
916
+ </pre>
917
+ </div>
918
+ <p>Notice that only <em>one</em> migration was copied over here. This is because the first
919
+ two migrations were copied over the first time this command was run.</p><div class="code_container">
920
+ <pre class="brush: plain; gutter: false; toolbar: false">
921
+ NOTE Migration [timestamp]_create_blorgh_articles.rb from blorgh has been
922
+ skipped. Migration with the same name already exists. NOTE Migration
923
+ [timestamp]_create_blorgh_comments.rb from blorgh has been skipped. Migration
924
+ with the same name already exists. Copied migration
925
+ [timestamp]_add_author_id_to_blorgh_articles.rb from blorgh
926
+
927
+ </pre>
928
+ </div>
929
+ <p>Run the migration using:</p><div class="code_container">
930
+ <pre class="brush: plain; gutter: false; toolbar: false">
931
+ $ rake db:migrate
932
+
933
+ </pre>
934
+ </div>
935
+ <p>Now with all the pieces in place, an action will take place that will associate
936
+ an author - represented by a record in the <code>users</code> table - with an article,
937
+ represented by the <code>blorgh_articles</code> table from the engine.</p><p>Finally, the author's name should be displayed on the article's page. Add this code
938
+ above the "Title" output inside <code>app/views/blorgh/articles/show.html.erb</code>:</p><div class="code_container">
939
+ <pre class="brush: plain; gutter: false; toolbar: false">
940
+ &lt;p&gt;
941
+ &lt;b&gt;Author:&lt;/b&gt;
942
+ &lt;%= @article.author %&gt;
943
+ &lt;/p&gt;
944
+
945
+ </pre>
946
+ </div>
947
+ <p>By outputting <code>@article.author</code> using the <code>&lt;%=</code> tag, the <code>to_s</code> method will be
948
+ called on the object. By default, this will look quite ugly:</p><div class="code_container">
949
+ <pre class="brush: plain; gutter: false; toolbar: false">
950
+ #&lt;User:0x00000100ccb3b0&gt;
951
+
952
+ </pre>
953
+ </div>
954
+ <p>This is undesirable. It would be much better to have the user's name there. To
955
+ do this, add a <code>to_s</code> method to the <code>User</code> class within the application:</p><div class="code_container">
956
+ <pre class="brush: ruby; gutter: false; toolbar: false">
957
+ def to_s
958
+ name
959
+ end
960
+
961
+ </pre>
962
+ </div>
963
+ <p>Now instead of the ugly Ruby object output, the author's name will be displayed.</p><h5 id="using-a-controller-provided-by-the-application">4.3.2 Using a Controller Provided by the Application</h5><p>Because Rails controllers generally share code for things like authentication
964
+ and accessing session variables, they inherit from <code>ApplicationController</code> by
965
+ default. Rails engines, however are scoped to run independently from the main
966
+ application, so each engine gets a scoped <code>ApplicationController</code>. This
967
+ namespace prevents code collisions, but often engine controllers need to access
968
+ methods in the main application's <code>ApplicationController</code>. An easy way to
969
+ provide this access is to change the engine's scoped <code>ApplicationController</code> to
970
+ inherit from the main application's <code>ApplicationController</code>. For our Blorgh
971
+ engine this would be done by changing
972
+ <code>app/controllers/blorgh/application_controller.rb</code> to look like:</p><div class="code_container">
973
+ <pre class="brush: ruby; gutter: false; toolbar: false">
974
+ class Blorgh::ApplicationController &lt; ApplicationController
975
+ end
976
+
977
+ </pre>
978
+ </div>
979
+ <p>By default, the engine's controllers inherit from
980
+ <code>Blorgh::ApplicationController</code>. So, after making this change they will have
981
+ access to the main application's <code>ApplicationController</code>, as though they were
982
+ part of the main application.</p><p>This change does require that the engine is run from a Rails application that
983
+ has an <code>ApplicationController</code>.</p><h4 id="configuring-an-engine">4.4 Configuring an Engine</h4><p>This section covers how to make the <code>User</code> class configurable, followed by
984
+ general configuration tips for the engine.</p><h5 id="setting-configuration-settings-in-the-application">4.4.1 Setting Configuration Settings in the Application</h5><p>The next step is to make the class that represents a <code>User</code> in the application
985
+ customizable for the engine. This is because that class may not always be
986
+ <code>User</code>, as previously explained. To make this setting customizable, the engine
987
+ will have a configuration setting called <code>author_class</code> that will be used to
988
+ specify which class represents users inside the application.</p><p>To define this configuration setting, you should use a <code>mattr_accessor</code> inside
989
+ the <code>Blorgh</code> module for the engine. Add this line to <code>lib/blorgh.rb</code> inside the
990
+ engine:</p><div class="code_container">
991
+ <pre class="brush: ruby; gutter: false; toolbar: false">
992
+ mattr_accessor :author_class
993
+
994
+ </pre>
995
+ </div>
996
+ <p>This method works like its brothers, <code>attr_accessor</code> and <code>cattr_accessor</code>, but
997
+ provides a setter and getter method on the module with the specified name. To
998
+ use it, it must be referenced using <code>Blorgh.author_class</code>.</p><p>The next step is to switch the <code>Blorgh::Article</code> model over to this new setting.
999
+ Change the <code>belongs_to</code> association inside this model
1000
+ (<code>app/models/blorgh/article.rb</code>) to this:</p><div class="code_container">
1001
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1002
+ belongs_to :author, class_name: Blorgh.author_class
1003
+
1004
+ </pre>
1005
+ </div>
1006
+ <p>The <code>set_author</code> method in the <code>Blorgh::Article</code> model should also use this class:</p><div class="code_container">
1007
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1008
+ self.author = Blorgh.author_class.constantize.find_or_create_by(name: author_name)
1009
+
1010
+ </pre>
1011
+ </div>
1012
+ <p>To save having to call <code>constantize</code> on the <code>author_class</code> result all the time,
1013
+ you could instead just override the <code>author_class</code> getter method inside the
1014
+ <code>Blorgh</code> module in the <code>lib/blorgh.rb</code> file to always call <code>constantize</code> on the
1015
+ saved value before returning the result:</p><div class="code_container">
1016
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1017
+ def self.author_class
1018
+ @@author_class.constantize
1019
+ end
1020
+
1021
+ </pre>
1022
+ </div>
1023
+ <p>This would then turn the above code for <code>set_author</code> into this:</p><div class="code_container">
1024
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1025
+ self.author = Blorgh.author_class.find_or_create_by(name: author_name)
1026
+
1027
+ </pre>
1028
+ </div>
1029
+ <p>Resulting in something a little shorter, and more implicit in its behavior. The
1030
+ <code>author_class</code> method should always return a <code>Class</code> object.</p><p>Since we changed the <code>author_class</code> method to return a <code>Class</code> instead of a
1031
+ <code>String</code>, we must also modify our <code>belongs_to</code> definition in the <code>Blorgh::Article</code>
1032
+ model:</p><div class="code_container">
1033
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1034
+ belongs_to :author, class_name: Blorgh.author_class.to_s
1035
+
1036
+ </pre>
1037
+ </div>
1038
+ <p>To set this configuration setting within the application, an initializer should
1039
+ be used. By using an initializer, the configuration will be set up before the
1040
+ application starts and calls the engine's models, which may depend on this
1041
+ configuration setting existing.</p><p>Create a new initializer at <code>config/initializers/blorgh.rb</code> inside the
1042
+ application where the <code>blorgh</code> engine is installed and put this content in it:</p><div class="code_container">
1043
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1044
+ Blorgh.author_class = "User"
1045
+
1046
+ </pre>
1047
+ </div>
1048
+ <div class="warning"><p>It's very important here to use the <code>String</code> version of the class,
1049
+ rather than the class itself. If you were to use the class, Rails would attempt
1050
+ to load that class and then reference the related table. This could lead to
1051
+ problems if the table wasn't already existing. Therefore, a <code>String</code> should be
1052
+ used and then converted to a class using <code>constantize</code> in the engine later on.</p></div><p>Go ahead and try to create a new article. You will see that it works exactly in the
1053
+ same way as before, except this time the engine is using the configuration
1054
+ setting in <code>config/initializers/blorgh.rb</code> to learn what the class is.</p><p>There are now no strict dependencies on what the class is, only what the API for
1055
+ the class must be. The engine simply requires this class to define a
1056
+ <code>find_or_create_by</code> method which returns an object of that class, to be
1057
+ associated with an article when it's created. This object, of course, should have
1058
+ some sort of identifier by which it can be referenced.</p><h5 id="general-engine-configuration">4.4.2 General Engine Configuration</h5><p>Within an engine, there may come a time where you wish to use things such as
1059
+ initializers, internationalization or other configuration options. The great
1060
+ news is that these things are entirely possible, because a Rails engine shares
1061
+ much the same functionality as a Rails application. In fact, a Rails
1062
+ application's functionality is actually a superset of what is provided by
1063
+ engines!</p><p>If you wish to use an initializer - code that should run before the engine is
1064
+ loaded - the place for it is the <code>config/initializers</code> folder. This directory's
1065
+ functionality is explained in the <a href="configuring.html#initializers">Initializers
1066
+ section</a> of the Configuring guide, and works
1067
+ precisely the same way as the <code>config/initializers</code> directory inside an
1068
+ application. The same thing goes if you want to use a standard initializer.</p><p>For locales, simply place the locale files in the <code>config/locales</code> directory,
1069
+ just like you would in an application.</p><h3 id="testing-an-engine">5 Testing an engine</h3><p>When an engine is generated, there is a smaller dummy application created inside
1070
+ it at <code>test/dummy</code>. This application is used as a mounting point for the engine,
1071
+ to make testing the engine extremely simple. You may extend this application by
1072
+ generating controllers, models or views from within the directory, and then use
1073
+ those to test your engine.</p><p>The <code>test</code> directory should be treated like a typical Rails testing environment,
1074
+ allowing for unit, functional and integration tests.</p><h4 id="functional-tests">5.1 Functional Tests</h4><p>A matter worth taking into consideration when writing functional tests is that
1075
+ the tests are going to be running on an application - the <code>test/dummy</code>
1076
+ application - rather than your engine. This is due to the setup of the testing
1077
+ environment; an engine needs an application as a host for testing its main
1078
+ functionality, especially controllers. This means that if you were to make a
1079
+ typical <code>GET</code> to a controller in a controller's functional test like this:</p><div class="code_container">
1080
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1081
+ get :index
1082
+
1083
+ </pre>
1084
+ </div>
1085
+ <p>It may not function correctly. This is because the application doesn't know how
1086
+ to route these requests to the engine unless you explicitly tell it <strong>how</strong>. To
1087
+ do this, you must also pass the <code>:use_route</code> option as a parameter on these
1088
+ requests:</p><div class="code_container">
1089
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1090
+ get :index, use_route: :blorgh
1091
+
1092
+ </pre>
1093
+ </div>
1094
+ <p>This tells the application that you still want to perform a <code>GET</code> request to the
1095
+ <code>index</code> action of this controller, but you want to use the engine's route to get
1096
+ there, rather than the application's one.</p><p>Another way to do this is to assign the <code>@routes</code> instance variable to <code>Engine.routes</code> in your test setup:</p><div class="code_container">
1097
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1098
+ setup do
1099
+ @routes = Engine.routes
1100
+ end
1101
+
1102
+ </pre>
1103
+ </div>
1104
+ <p>This will also ensure url helpers for the engine will work as expected in your tests.</p><h3 id="improving-engine-functionality">6 Improving engine functionality</h3><p>This section explains how to add and/or override engine MVC functionality in the
1105
+ main Rails application.</p><h4 id="overriding-models-and-controllers">6.1 Overriding Models and Controllers</h4><p>Engine model and controller classes can be extended by open classing them in the
1106
+ main Rails application (since model and controller classes are just Ruby classes
1107
+ that inherit Rails specific functionality). Open classing an Engine class
1108
+ redefines it for use in the main application. This is usually implemented by
1109
+ using the decorator pattern.</p><p>For simple class modifications, use <code>Class#class_eval</code>. For complex class
1110
+ modifications, consider using <code>ActiveSupport::Concern</code>.</p><h5 id="a-note-on-decorators-and-loading-code">6.1.1 A note on Decorators and Loading Code</h5><p>Because these decorators are not referenced by your Rails application itself,
1111
+ Rails' autoloading system will not kick in and load your decorators. This means
1112
+ that you need to require them yourself.</p><p>Here is some sample code to do this:</p><div class="code_container">
1113
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1114
+ # lib/blorgh/engine.rb
1115
+ module Blorgh
1116
+ class Engine &lt; ::Rails::Engine
1117
+ isolate_namespace Blorgh
1118
+
1119
+ config.to_prepare do
1120
+ Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
1121
+ require_dependency(c)
1122
+ end
1123
+ end
1124
+ end
1125
+ end
1126
+
1127
+ </pre>
1128
+ </div>
1129
+ <p>This doesn't apply to just Decorators, but anything that you add in an engine
1130
+ that isn't referenced by your main application.</p><h5 id="implementing-decorator-pattern-using-class#class_eval">6.1.2 Implementing Decorator Pattern Using Class#class_eval</h5><p><strong>Adding</strong> <code>Article#time_since_created</code>:</p><div class="code_container">
1131
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1132
+ # MyApp/app/decorators/models/blorgh/article_decorator.rb
1133
+
1134
+ Blorgh::Article.class_eval do
1135
+ def time_since_created
1136
+ Time.current - created_at
1137
+ end
1138
+ end
1139
+
1140
+ </pre>
1141
+ </div>
1142
+ <div class="code_container">
1143
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1144
+ # Blorgh/app/models/article.rb
1145
+
1146
+ class Article &lt; ActiveRecord::Base
1147
+ has_many :comments
1148
+ end
1149
+
1150
+ </pre>
1151
+ </div>
1152
+ <p><strong>Overriding</strong> <code>Article#summary</code>:</p><div class="code_container">
1153
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1154
+ # MyApp/app/decorators/models/blorgh/article_decorator.rb
1155
+
1156
+ Blorgh::Article.class_eval do
1157
+ def summary
1158
+ "#{title} - #{truncate(text)}"
1159
+ end
1160
+ end
1161
+
1162
+ </pre>
1163
+ </div>
1164
+ <div class="code_container">
1165
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1166
+ # Blorgh/app/models/article.rb
1167
+
1168
+ class Article &lt; ActiveRecord::Base
1169
+ has_many :comments
1170
+ def summary
1171
+ "#{title}"
1172
+ end
1173
+ end
1174
+
1175
+ </pre>
1176
+ </div>
1177
+ <h5 id="implementing-decorator-pattern-using-activesupport::concern">6.1.3 Implementing Decorator Pattern Using ActiveSupport::Concern</h5><p>Using <code>Class#class_eval</code> is great for simple adjustments, but for more complex
1178
+ class modifications, you might want to consider using <a href="http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html"><code>ActiveSupport::Concern</code></a>.
1179
+ ActiveSupport::Concern manages load order of interlinked dependent modules and
1180
+ classes at run time allowing you to significantly modularize your code.</p><p><strong>Adding</strong> <code>Article#time_since_created</code> and <strong>Overriding</strong> <code>Article#summary</code>:</p><div class="code_container">
1181
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1182
+ # MyApp/app/models/blorgh/article.rb
1183
+
1184
+ class Blorgh::Article &lt; ActiveRecord::Base
1185
+ include Blorgh::Concerns::Models::Article
1186
+
1187
+ def time_since_created
1188
+ Time.current - created_at
1189
+ end
1190
+
1191
+ def summary
1192
+ "#{title} - #{truncate(text)}"
1193
+ end
1194
+ end
1195
+
1196
+ </pre>
1197
+ </div>
1198
+ <div class="code_container">
1199
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1200
+ # Blorgh/app/models/article.rb
1201
+
1202
+ class Article &lt; ActiveRecord::Base
1203
+ include Blorgh::Concerns::Models::Article
1204
+ end
1205
+
1206
+ </pre>
1207
+ </div>
1208
+ <div class="code_container">
1209
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1210
+ # Blorgh/lib/concerns/models/article
1211
+
1212
+ module Blorgh::Concerns::Models::Article
1213
+ extend ActiveSupport::Concern
1214
+
1215
+ # 'included do' causes the included code to be evaluated in the
1216
+ # context where it is included (article.rb), rather than being
1217
+ # executed in the module's context (blorgh/concerns/models/article).
1218
+ included do
1219
+ attr_accessor :author_name
1220
+ belongs_to :author, class_name: "User"
1221
+
1222
+ before_save :set_author
1223
+
1224
+ private
1225
+ def set_author
1226
+ self.author = User.find_or_create_by(name: author_name)
1227
+ end
1228
+ end
1229
+
1230
+ def summary
1231
+ "#{title}"
1232
+ end
1233
+
1234
+ module ClassMethods
1235
+ def some_class_method
1236
+ 'some class method string'
1237
+ end
1238
+ end
1239
+ end
1240
+
1241
+ </pre>
1242
+ </div>
1243
+ <h4 id="overriding-views">6.2 Overriding Views</h4><p>When Rails looks for a view to render, it will first look in the <code>app/views</code>
1244
+ directory of the application. If it cannot find the view there, it will check in
1245
+ the <code>app/views</code> directories of all engines that have this directory.</p><p>When the application is asked to render the view for <code>Blorgh::ArticlesController</code>'s
1246
+ index action, it will first look for the path
1247
+ <code>app/views/blorgh/articles/index.html.erb</code> within the application. If it cannot
1248
+ find it, it will look inside the engine.</p><p>You can override this view in the application by simply creating a new file at
1249
+ <code>app/views/blorgh/articles/index.html.erb</code>. Then you can completely change what
1250
+ this view would normally output.</p><p>Try this now by creating a new file at <code>app/views/blorgh/articles/index.html.erb</code>
1251
+ and put this content in it:</p><div class="code_container">
1252
+ <pre class="brush: plain; gutter: false; toolbar: false">
1253
+ &lt;h1&gt;Articles&lt;/h1&gt;
1254
+ &lt;%= link_to "New Article", new_article_path %&gt;
1255
+ &lt;% @articles.each do |article| %&gt;
1256
+ &lt;h2&gt;&lt;%= article.title %&gt;&lt;/h2&gt;
1257
+ &lt;small&gt;By &lt;%= article.author %&gt;&lt;/small&gt;
1258
+ &lt;%= simple_format(article.text) %&gt;
1259
+ &lt;hr&gt;
1260
+ &lt;% end %&gt;
1261
+
1262
+ </pre>
1263
+ </div>
1264
+ <h4 id="routes">6.3 Routes</h4><p>Routes inside an engine are isolated from the application by default. This is
1265
+ done by the <code>isolate_namespace</code> call inside the <code>Engine</code> class. This essentially
1266
+ means that the application and its engines can have identically named routes and
1267
+ they will not clash.</p><p>Routes inside an engine are drawn on the <code>Engine</code> class within
1268
+ <code>config/routes.rb</code>, like this:</p><div class="code_container">
1269
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1270
+ Blorgh::Engine.routes.draw do
1271
+ resources :articles
1272
+ end
1273
+
1274
+ </pre>
1275
+ </div>
1276
+ <p>By having isolated routes such as this, if you wish to link to an area of an
1277
+ engine from within an application, you will need to use the engine's routing
1278
+ proxy method. Calls to normal routing methods such as <code>articles_path</code> may end up
1279
+ going to undesired locations if both the application and the engine have such a
1280
+ helper defined.</p><p>For instance, the following example would go to the application's <code>articles_path</code>
1281
+ if that template was rendered from the application, or the engine's <code>articles_path</code>
1282
+ if it was rendered from the engine:</p><div class="code_container">
1283
+ <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
1284
+ &lt;%= link_to "Blog articles", articles_path %&gt;
1285
+
1286
+ </pre>
1287
+ </div>
1288
+ <p>To make this route always use the engine's <code>articles_path</code> routing helper method,
1289
+ we must call the method on the routing proxy method that shares the same name as
1290
+ the engine.</p><div class="code_container">
1291
+ <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
1292
+ &lt;%= link_to "Blog articles", blorgh.articles_path %&gt;
1293
+
1294
+ </pre>
1295
+ </div>
1296
+ <p>If you wish to reference the application inside the engine in a similar way, use
1297
+ the <code>main_app</code> helper:</p><div class="code_container">
1298
+ <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
1299
+ &lt;%= link_to "Home", main_app.root_path %&gt;
1300
+
1301
+ </pre>
1302
+ </div>
1303
+ <p>If you were to use this inside an engine, it would <strong>always</strong> go to the
1304
+ application's root. If you were to leave off the <code>main_app</code> "routing proxy"
1305
+ method call, it could potentially go to the engine's or application's root,
1306
+ depending on where it was called from.</p><p>If a template rendered from within an engine attempts to use one of the
1307
+ application's routing helper methods, it may result in an undefined method call.
1308
+ If you encounter such an issue, ensure that you're not attempting to call the
1309
+ application's routing methods without the <code>main_app</code> prefix from within the
1310
+ engine.</p><h4 id="assets">6.4 Assets</h4><p>Assets within an engine work in an identical way to a full application. Because
1311
+ the engine class inherits from <code>Rails::Engine</code>, the application will know to
1312
+ look up assets in the engine's 'app/assets' and 'lib/assets' directories.</p><p>Like all of the other components of an engine, the assets should be namespaced.
1313
+ This means that if you have an asset called <code>style.css</code>, it should be placed at
1314
+ <code>app/assets/stylesheets/[engine name]/style.css</code>, rather than
1315
+ <code>app/assets/stylesheets/style.css</code>. If this asset isn't namespaced, there is a
1316
+ possibility that the host application could have an asset named identically, in
1317
+ which case the application's asset would take precedence and the engine's one
1318
+ would be ignored.</p><p>Imagine that you did have an asset located at
1319
+ <code>app/assets/stylesheets/blorgh/style.css</code> To include this asset inside an
1320
+ application, just use <code>stylesheet_link_tag</code> and reference the asset as if it
1321
+ were inside the engine:</p><div class="code_container">
1322
+ <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
1323
+ &lt;%= stylesheet_link_tag "blorgh/style.css" %&gt;
1324
+
1325
+ </pre>
1326
+ </div>
1327
+ <p>You can also specify these assets as dependencies of other assets using Asset
1328
+ Pipeline require statements in processed files:</p><div class="code_container">
1329
+ <pre class="brush: plain; gutter: false; toolbar: false">
1330
+ /*
1331
+ *= require blorgh/style
1332
+ */
1333
+
1334
+ </pre>
1335
+ </div>
1336
+ <div class="info"><p>Remember that in order to use languages like Sass or CoffeeScript, you
1337
+ should add the relevant library to your engine's <code>.gemspec</code>.</p></div><h4 id="separate-assets-&amp;-precompiling">6.5 Separate Assets &amp; Precompiling</h4><p>There are some situations where your engine's assets are not required by the
1338
+ host application. For example, say that you've created an admin functionality
1339
+ that only exists for your engine. In this case, the host application doesn't
1340
+ need to require <code>admin.css</code> or <code>admin.js</code>. Only the gem's admin layout needs
1341
+ these assets. It doesn't make sense for the host app to include
1342
+ <code>"blorgh/admin.css"</code> in its stylesheets. In this situation, you should
1343
+ explicitly define these assets for precompilation. This tells sprockets to add
1344
+ your engine assets when <code>rake assets:precompile</code> is triggered.</p><p>You can define assets for precompilation in <code>engine.rb</code>:</p><div class="code_container">
1345
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1346
+ initializer "blorgh.assets.precompile" do |app|
1347
+ app.config.assets.precompile += %w(admin.css admin.js)
1348
+ end
1349
+
1350
+ </pre>
1351
+ </div>
1352
+ <p>For more information, read the <a href="asset_pipeline.html">Asset Pipeline guide</a>.</p><h4 id="other-gem-dependencies">6.6 Other Gem Dependencies</h4><p>Gem dependencies inside an engine should be specified inside the <code>.gemspec</code> file
1353
+ at the root of the engine. The reason is that the engine may be installed as a
1354
+ gem. If dependencies were to be specified inside the <code>Gemfile</code>, these would not
1355
+ be recognized by a traditional gem install and so they would not be installed,
1356
+ causing the engine to malfunction.</p><p>To specify a dependency that should be installed with the engine during a
1357
+ traditional <code>gem install</code>, specify it inside the <code>Gem::Specification</code> block
1358
+ inside the <code>.gemspec</code> file in the engine:</p><div class="code_container">
1359
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1360
+ s.add_dependency "moo"
1361
+
1362
+ </pre>
1363
+ </div>
1364
+ <p>To specify a dependency that should only be installed as a development
1365
+ dependency of the application, specify it like this:</p><div class="code_container">
1366
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1367
+ s.add_development_dependency "moo"
1368
+
1369
+ </pre>
1370
+ </div>
1371
+ <p>Both kinds of dependencies will be installed when <code>bundle install</code> is run inside
1372
+ of the application. The development dependencies for the gem will only be used
1373
+ when the tests for the engine are running.</p><p>Note that if you want to immediately require dependencies when the engine is
1374
+ required, you should require them before the engine's initialization. For
1375
+ example:</p><div class="code_container">
1376
+ <pre class="brush: ruby; gutter: false; toolbar: false">
1377
+ require 'other_engine/engine'
1378
+ require 'yet_another_engine/engine'
1379
+
1380
+ module MyEngine
1381
+ class Engine &lt; ::Rails::Engine
1382
+ end
1383
+ end
1384
+
1385
+ </pre>
1386
+ </div>
1387
+
1388
+
1389
+ <h3>Feedback</h3>
1390
+ <p>
1391
+ You're encouraged to help improve the quality of this guide.
1392
+ </p>
1393
+ <p>
1394
+ Please contribute if you see any typos or factual errors.
1395
+ To get started, you can read our <a href="http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#contributing-to-the-rails-documentation">documentation contributions</a> section.
1396
+ </p>
1397
+ <p>
1398
+ You may also find incomplete content, or stuff that is not up to date.
1399
+ Please do add any missing documentation for master. Make sure to check
1400
+ <a href="http://edgeguides.rubyonrails.org">Edge Guides</a> first to verify
1401
+ if the issues are already fixed or not on the master branch.
1402
+ Check the <a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a>
1403
+ for style and conventions.
1404
+ </p>
1405
+ <p>
1406
+ If for whatever reason you spot something to fix but cannot patch it yourself, please
1407
+ <a href="https://github.com/rails/rails/issues">open an issue</a>.
1408
+ </p>
1409
+ <p>And last but not least, any kind of discussion regarding Ruby on Rails
1410
+ documentation is very welcome in the <a href="http://groups.google.com/group/rubyonrails-docs">rubyonrails-docs mailing list</a>.
1411
+ </p>
1412
+ </div>
1413
+ </div>
1414
+ </div>
1415
+
1416
+ <hr class="hide" />
1417
+ <div id="footer">
1418
+ <div class="wrapper">
1419
+ <p>This work is licensed under a <a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International</a> License</p>
1420
+ <p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p>
1421
+
1422
+ </div>
1423
+ </div>
1424
+
1425
+ <script type="text/javascript" src="javascripts/jquery.min.js"></script>
1426
+ <script type="text/javascript" src="javascripts/responsive-tables.js"></script>
1427
+ <script type="text/javascript" src="javascripts/guides.js"></script>
1428
+ <script type="text/javascript" src="javascripts/syntaxhighlighter/shCore.js"></script>
1429
+ <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushRuby.js"></script>
1430
+ <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushXml.js"></script>
1431
+ <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushSql.js"></script>
1432
+ <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushPlain.js"></script>
1433
+ <script type="text/javascript">
1434
+ SyntaxHighlighter.all();
1435
+ $(guidesIndex.bind);
1436
+ </script>
1437
+ </body>
1438
+ </html>