CINXE.COM
Creating and Customizing Rails Generators & Templates — Ruby on Rails Guides
<!doctype html> <html dir="ltr" lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Creating and Customizing Rails Generators & Templates — Ruby on Rails Guides</title> <link rel="stylesheet" type="text/css" href="stylesheets/style-071e355820fc155a5c40ef8a1c0c4971.css" data-turbo-track="reload"> <link rel="stylesheet" type="text/css" href="stylesheets/print-a87ee66d50ce96bb83ac082f1249fe3e.css" media="print"> <link rel="stylesheet" type="text/css" href="stylesheets/highlight-a0d2133dd0073968b2d33b1f1360a2a3.css" data-turbo-track="reload"> <link rel="icon" href="images/favicon.ico" sizes="any"> <link rel="apple-touch-icon" href="images/icon.png"> <script src="javascripts/@hotwired--turbo-764f59c7edbeb902a9068c0340dd274e.js" data-turbo-track="reload"></script> <script src="javascripts/clipboard-8b7aed6f069f0cf58eeae353cd2f898b.js" data-turbo-track="reload"></script> <script src="javascripts/guides-897790ae3777ddd81bd4953f7ec99835.js" data-turbo-track="reload"></script> <meta property="og:title" content="Creating and Customizing Rails Generators & Templates — Ruby on Rails Guides" /> <meta name="description" content="Creating and Customizing Rails Generators &amp; TemplatesRails generators are an essential tool for improving your workflow. With this guide you will learn how to create generators and customize existing ones.After reading this guide, you will know: How to see which generators are available in your application. How to create a generator using templates. How Rails searches for generators before invoking them. How to customize your scaffold by overriding generator templates. How to customize your scaffold by overriding generators. How to use fallbacks to avoid overwriting a huge set of generators. How to create an application template." /> <meta property="og:description" content="Creating and Customizing Rails Generators &amp; TemplatesRails generators are an essential tool for improving your workflow. With this guide you will learn how to create generators and customize existing ones.After reading this guide, you will know: How to see which generators are available in your application. How to create a generator using templates. How Rails searches for generators before invoking them. How to customize your scaffold by overriding generator templates. How to customize your scaffold by overriding generators. How to use fallbacks to avoid overwriting a huge set of generators. How to create an application template." /> <meta property="og:locale" content="en_US" /> <meta property="og:site_name" content="Ruby on Rails Guides" /> <meta property="og:image" content="https://avatars.githubusercontent.com/u/4223" /> <meta property="og:type" content="website" /> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Arabic:wght@100..900&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Heebo:wght@100..900&family=Noto+Sans+Arabic:wght@100..900&display=swap" rel="stylesheet"> <meta name="theme-color" content="#C81418"> </head> <body dir="ltr" class="guide no-js"> <script> document.body.classList.remove('no-js') </script> <a id="main-skip-link" href="#main" class="skip-link" data-turbo="false"> Skip to main content </a> <div id="mobile-navigation-bar"> <div class="wrapper"> <strong class="more-info-label">More at <a href="https://rubyonrails.org/">rubyonrails.org:</a> </strong> <button type="button" class="js-only red-button more-info-button" id="more-info" aria-controls="more-info-links" aria-expanded="false"> More Ruby on Rails </button> <ul id="more-info-links" class="more-info-links hidden"> <li class="more-info"><a href="https://rubyonrails.org/blog">Blog</a></li> <li class="more-info"><a href="https://guides.rubyonrails.org/">Guides</a></li> <li class="more-info"><a href="https://api.rubyonrails.org/">API</a></li> <li class="more-info"><a href="https://discuss.rubyonrails.org/">Forum</a></li> <li class="more-info"><a href="https://github.com/rails/rails">Contribute on GitHub</a></li> </ul> </div> </div> <header id="page-header"> <div class="wrapper clearfix"> <nav id="feature-nav"> <div class="header-logo"> <a href="index.html" title="Guides home for v8.0.0 Guides">Guides</a> <span id="version-switcher" class="js-only"> <label for="version-switcher-select">Version: <span class="visibly-hidden">pick from the list to go to that Rails version's guides</span></label> <select id="version-switcher-select" class="guides-version"> <option value="https://edgeguides.rubyonrails.org/">Edge</option> <option value="https://guides.rubyonrails.org/v8.0/" selected>8.0</option> <option value="https://guides.rubyonrails.org/v7.2/">7.2</option> <option value="https://guides.rubyonrails.org/v7.1/">7.1</option> <option value="https://guides.rubyonrails.org/v7.0/">7.0</option> <option value="https://guides.rubyonrails.org/v6.1/">6.1</option> <option value="https://guides.rubyonrails.org/v6.0/">6.0</option> <option value="https://guides.rubyonrails.org/v5.2/">5.2</option> <option value="https://guides.rubyonrails.org/v5.1/">5.1</option> <option value="https://guides.rubyonrails.org/v5.0/">5.0</option> <option value="https://guides.rubyonrails.org/v4.2/">4.2</option> <option value="https://guides.rubyonrails.org/v4.1/">4.1</option> <option value="https://guides.rubyonrails.org/v4.0/">4.0</option> <option value="https://guides.rubyonrails.org/v3.2/">3.2</option> <option value="https://guides.rubyonrails.org/v3.1/">3.1</option> <option value="https://guides.rubyonrails.org/v3.0/">3.0</option> <option value="https://guides.rubyonrails.org/v2.3/">2.3</option> </select> </span> </div> <ul class="nav"> <li><a class="nav-item" id="home_nav" href="https://rubyonrails.org/">Home</a></li> <li class="guides-index guides-index-large"> <a href="index.html" id="guides-menu-button" data-aria-controls="guides" data-aria-expanded="false" class="guides-index-item nav-item">Guides Index</a> <div id="guides" class="clearfix" style="display: none;"> <hr /> <dl class="guides-section-container"> <div class="guides-section"> <dt>Start Here</dt> <dd><a href="getting_started.html">Getting Started with Rails</a></dd> </div> <div class="guides-section"> <dt>Models</dt> <dd><a href="active_record_basics.html">Active Record Basics</a></dd> <dd><a href="active_record_migrations.html">Active Record Migrations</a></dd> <dd><a href="active_record_validations.html">Active Record Validations</a></dd> <dd><a href="active_record_callbacks.html">Active Record Callbacks</a></dd> <dd><a href="association_basics.html">Active Record Associations</a></dd> <dd><a href="active_record_querying.html">Active Record Query Interface</a></dd> <dd><a href="active_model_basics.html">Active Model Basics</a></dd> </div> <div class="guides-section"> <dt>Views</dt> <dd><a href="action_view_overview.html">Action View Overview</a></dd> <dd><a href="layouts_and_rendering.html">Layouts and Rendering in Rails</a></dd> <dd><a href="action_view_helpers.html">Action View Helpers</a></dd> <dd><a href="form_helpers.html">Action View Form Helpers</a></dd> </div> <div class="guides-section"> <dt>Controllers</dt> <dd><a href="action_controller_overview.html">Action Controller Overview</a></dd> <dd><a href="routing.html">Rails Routing from the Outside In</a></dd> </div> <div class="guides-section"> <dt>Other Components</dt> <dd><a href="active_support_core_extensions.html">Active Support Core Extensions</a></dd> <dd><a href="action_mailer_basics.html">Action Mailer Basics</a></dd> <dd><a href="action_mailbox_basics.html">Action Mailbox Basics</a></dd> <dd><a href="action_text_overview.html">Action Text Overview</a></dd> <dd><a href="active_job_basics.html">Active Job Basics</a></dd> <dd><a href="active_storage_overview.html">Active Storage Overview</a></dd> <dd><a href="action_cable_overview.html">Action Cable Overview</a></dd> </div> <div class="guides-section"> <dt>Digging Deeper</dt> <dd><a href="i18n.html">Rails Internationalization (I18n) API</a></dd> <dd><a href="testing.html">Testing Rails Applications</a></dd> <dd><a href="security.html">Securing Rails Applications</a></dd> <dd><a href="error_reporting.html">Error Reporting in Rails Applications</a></dd> <dd><a href="debugging_rails_applications.html">Debugging Rails Applications</a></dd> <dd><a href="configuring.html">Configuring Rails Applications</a></dd> <dd><a href="command_line.html">The Rails Command Line</a></dd> <dd><a href="asset_pipeline.html">The Asset Pipeline</a></dd> <dd><a href="working_with_javascript_in_rails.html">Working with JavaScript in Rails</a></dd> <dd><a href="autoloading_and_reloading_constants.html">Autoloading and Reloading</a></dd> <dd><a href="caching_with_rails.html">Caching with Rails: An Overview</a></dd> <dd><a href="api_app.html">Using Rails for API-only Applications</a></dd> <dd><a href="tuning_performance_for_deployment.html">Tuning Performance for Deployment</a></dd> </div> <div class="guides-section"> <dt>Advanced Active Record</dt> <dd><a href="active_record_multiple_databases.html">Multiple Databases</a></dd> <dd><a href="active_record_composite_primary_keys.html">Composite Primary Keys</a></dd> </div> <div class="guides-section"> <dt>Extending Rails</dt> <dd><a href="rails_on_rack.html">Rails on Rack</a></dd> <dd><a href="generators.html">Creating and Customizing Rails Generators & Templates</a></dd> </div> <div class="guides-section"> <dt>Contributing</dt> <dd><a href="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</a></dd> <dd><a href="api_documentation_guidelines.html">API Documentation Guidelines</a></dd> <dd><a href="ruby_on_rails_guides_guidelines.html">Guides Guidelines</a></dd> <dd><a href="development_dependencies_install.html">Installing Rails Core Development Dependencies</a></dd> </div> <div class="guides-section"> <dt>Policies</dt> <dd><a href="maintenance_policy.html">Maintenance Policy</a></dd> </div> <div class="guides-section"> <dt>Release Notes</dt> <dd><a href="upgrading_ruby_on_rails.html">Upgrading Ruby on Rails</a></dd> <dd><a href="7_2_release_notes.html">Version 7.2 - August 2024</a></dd> <dd><a href="7_1_release_notes.html">Version 7.1 - October 2023</a></dd> <dd><a href="7_0_release_notes.html">Version 7.0 - December 2021</a></dd> <dd><a href="6_1_release_notes.html">Version 6.1 - December 2020</a></dd> <dd><a href="6_0_release_notes.html">Version 6.0 - August 2019</a></dd> <dd><a href="5_2_release_notes.html">Version 5.2 - April 2018</a></dd> <dd><a href="5_1_release_notes.html">Version 5.1 - April 2017</a></dd> <dd><a href="5_0_release_notes.html">Version 5.0 - June 2016</a></dd> <dd><a href="4_2_release_notes.html">Version 4.2 - December 2014</a></dd> <dd><a href="4_1_release_notes.html">Version 4.1 - April 2014</a></dd> <dd><a href="4_0_release_notes.html">Version 4.0 - June 2013</a></dd> <dd><a href="3_2_release_notes.html">Version 3.2 - January 2012</a></dd> <dd><a href="3_1_release_notes.html">Version 3.1 - August 2011</a></dd> <dd><a href="3_0_release_notes.html">Version 3.0 - August 2010</a></dd> <dd><a href="2_3_release_notes.html">Version 2.3 - March 2009</a></dd> <dd><a href="2_2_release_notes.html">Version 2.2 - November 2008</a></dd> </div> </dl> </div> </li> <li><a class="nav-item" href="contributing_to_ruby_on_rails.html">Contribute</a></li> <li class="guides-index guides-index-small js-only"> <label for="guides-selector"> Navigate to a guide: </label> <select id="guides-selector" class="guides-index-item nav-item"> <option value="index.html">Guides Index</option> <optgroup label="Start Here"> <option value="getting_started.html">Getting Started with Rails</option> </optgroup> <optgroup label="Models"> <option value="active_record_basics.html">Active Record Basics</option> <option value="active_record_migrations.html">Active Record Migrations</option> <option value="active_record_validations.html">Active Record Validations</option> <option value="active_record_callbacks.html">Active Record Callbacks</option> <option value="association_basics.html">Active Record Associations</option> <option value="active_record_querying.html">Active Record Query Interface</option> <option value="active_model_basics.html">Active Model Basics</option> </optgroup> <optgroup label="Views"> <option value="action_view_overview.html">Action View Overview</option> <option value="layouts_and_rendering.html">Layouts and Rendering in Rails</option> <option value="action_view_helpers.html">Action View Helpers</option> <option value="form_helpers.html">Action View Form Helpers</option> </optgroup> <optgroup label="Controllers"> <option value="action_controller_overview.html">Action Controller Overview</option> <option value="routing.html">Rails Routing from the Outside In</option> </optgroup> <optgroup label="Other Components"> <option value="active_support_core_extensions.html">Active Support Core Extensions</option> <option value="action_mailer_basics.html">Action Mailer Basics</option> <option value="action_mailbox_basics.html">Action Mailbox Basics</option> <option value="action_text_overview.html">Action Text Overview</option> <option value="active_job_basics.html">Active Job Basics</option> <option value="active_storage_overview.html">Active Storage Overview</option> <option value="action_cable_overview.html">Action Cable Overview</option> </optgroup> <optgroup label="Digging Deeper"> <option value="i18n.html">Rails Internationalization (I18n) API</option> <option value="testing.html">Testing Rails Applications</option> <option value="security.html">Securing Rails Applications</option> <option value="error_reporting.html">Error Reporting in Rails Applications</option> <option value="debugging_rails_applications.html">Debugging Rails Applications</option> <option value="configuring.html">Configuring Rails Applications</option> <option value="command_line.html">The Rails Command Line</option> <option value="asset_pipeline.html">The Asset Pipeline</option> <option value="working_with_javascript_in_rails.html">Working with JavaScript in Rails</option> <option value="autoloading_and_reloading_constants.html">Autoloading and Reloading</option> <option value="caching_with_rails.html">Caching with Rails: An Overview</option> <option value="api_app.html">Using Rails for API-only Applications</option> <option value="tuning_performance_for_deployment.html">Tuning Performance for Deployment</option> </optgroup> <optgroup label="Advanced Active Record"> <option value="active_record_multiple_databases.html">Multiple Databases</option> <option value="active_record_composite_primary_keys.html">Composite Primary Keys</option> </optgroup> <optgroup label="Extending Rails"> <option value="rails_on_rack.html">Rails on Rack</option> <option value="generators.html">Creating and Customizing Rails Generators & Templates</option> </optgroup> <optgroup label="Contributing"> <option value="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</option> <option value="api_documentation_guidelines.html">API Documentation Guidelines</option> <option value="ruby_on_rails_guides_guidelines.html">Guides Guidelines</option> <option value="development_dependencies_install.html">Installing Rails Core Development Dependencies</option> </optgroup> <optgroup label="Policies"> <option value="maintenance_policy.html">Maintenance Policy</option> </optgroup> <optgroup label="Release Notes"> <option value="upgrading_ruby_on_rails.html">Upgrading Ruby on Rails</option> <option value="7_2_release_notes.html">Version 7.2 - August 2024</option> <option value="7_1_release_notes.html">Version 7.1 - October 2023</option> <option value="7_0_release_notes.html">Version 7.0 - December 2021</option> <option value="6_1_release_notes.html">Version 6.1 - December 2020</option> <option value="6_0_release_notes.html">Version 6.0 - August 2019</option> <option value="5_2_release_notes.html">Version 5.2 - April 2018</option> <option value="5_1_release_notes.html">Version 5.1 - April 2017</option> <option value="5_0_release_notes.html">Version 5.0 - June 2016</option> <option value="4_2_release_notes.html">Version 4.2 - December 2014</option> <option value="4_1_release_notes.html">Version 4.1 - April 2014</option> <option value="4_0_release_notes.html">Version 4.0 - June 2013</option> <option value="3_2_release_notes.html">Version 3.2 - January 2012</option> <option value="3_1_release_notes.html">Version 3.1 - August 2011</option> <option value="3_0_release_notes.html">Version 3.0 - August 2010</option> <option value="2_3_release_notes.html">Version 2.3 - March 2009</option> <option value="2_2_release_notes.html">Version 2.2 - November 2008</option> </optgroup> </select> </li> </ul> </nav> </div> </header> <hr class="hide" /> <main id="main"> <article> <header id="feature"> <div class="wrapper"> <h1>Creating and Customizing Rails Generators & Templates</h1><p>Rails generators are an essential tool for improving your workflow. With this guide you will learn how to create generators and customize existing ones.</p><p>After reading this guide, you will know:</p> <ul> <li>How to see which generators are available in your application.</li> <li>How to create a generator using templates.</li> <li>How Rails searches for generators before invoking them.</li> <li>How to customize your scaffold by overriding generator templates.</li> <li>How to customize your scaffold by overriding generators.</li> <li>How to use fallbacks to avoid overwriting a huge set of generators.</li> <li>How to create an application template.</li> </ul> <nav id="column-side" aria-label="Chapter" class="guide-index" data-turbo="false"> <a id="chapter-nav-skip-link" href="#article-body" class="skip-link"> Skip to article body </a> <h2 class="chapter"> <picture aria-hidden="true"> <!-- Using the `source` HTML tag to set the dark theme image --> <source srcset="images/icon_book-close-bookmark-1-wht.svg" media="(prefers-color-scheme: dark)" /> <img src="images/icon_book-close-bookmark-1.svg" alt="Chapter Icon" /> </picture> Chapters </h2> <ol class="chapters"> <li><a href="#first-contact">First Contact</a></li> <li><a href="#creating-your-first-generator">Creating Your First Generator</a></li> <li><a href="#creating-generators-with-generators">Creating Generators with Generators</a></li> <li><a href="#generator-command-line-options">Generator Command Line Options</a></li> <li><a href="#generator-resolution">Generator Resolution</a></li> <li><a href="#overriding-rails-generator-templates">Overriding Rails Generator Templates</a></li> <li><a href="#overriding-rails-generators">Overriding Rails Generators</a> <ul> <li><a href="#generators-fallbacks">Generators Fallbacks</a></li> </ul></li> <li><a href="#application-templates">Application Templates</a></li> <li><a href="#generator-helper-methods">Generator Helper Methods</a></li> <li><a href="#testing-generators">Testing Generators</a></li> </ol> </nav> </div> </header> <div class="wrapper"> <div id="column-main"> <section id="article-body"> <h2 id="first-contact"><a class="anchorlink" href="#first-contact" data-turbo="false"><span>1</span> First Contact</a></h2><p>When you create an application using the <code>rails</code> command, you are in fact using a Rails generator. After that, you can get a list of all available generators by invoking <code>bin/rails generate</code>:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">rails </span>new myapp <span class="gp">$</span><span class="w"> </span><span class="nb">cd </span>myapp <span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate </code></pre> <button class="clipboard-button" data-clipboard-text="rails new myapp cd myapp bin/rails generate ">Copy</button> </div> <div class="interstitial note"><p>To create a Rails application we use the <code>rails</code> global command which uses the version of Rails installed via <code>gem install rails</code>. When inside the directory of your application, we use the <code>bin/rails</code> command which uses the version of Rails bundled with the application.</p></div><p>You will get a list of all generators that come with Rails. To see a detailed description of a particular generator, invoke the generator with the <code>--help</code> option. For example:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate scaffold <span class="nt">--help</span> </code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate scaffold --help ">Copy</button> </div> <h2 id="creating-your-first-generator"><a class="anchorlink" href="#creating-your-first-generator" data-turbo="false"><span>2</span> Creating Your First Generator</a></h2><p>Generators are built on top of <a href="https://github.com/rails/thor">Thor</a>, which provides powerful options for parsing and a great API for manipulating files.</p><p>Let's build a generator that creates an initializer file named <code>initializer.rb</code> inside <code>config/initializers</code>. The first step is to create a file at <code>lib/generators/initializer_generator.rb</code> with the following content:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="k">class</span> <span class="nc">InitializerGenerator</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Generators</span><span class="o">::</span><span class="no">Base</span> <span class="k">def</span> <span class="nf">create_initializer_file</span> <span class="n">create_file</span> <span class="s2">"config/initializers/initializer.rb"</span><span class="p">,</span> <span class="o"><<~</span><span class="no">RUBY</span><span class="sh"> # Add initialization content here </span><span class="no"> RUBY</span> <span class="k">end</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="class InitializerGenerator < Rails::Generators::Base def create_initializer_file create_file "config/initializers/initializer.rb", <<~RUBY # Add initialization content here RUBY end end ">Copy</button> </div> <p>Our new generator is quite simple: it inherits from <a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Base.html"><code>Rails::Generators::Base</code></a> and has one method definition. When a generator is invoked, each public method in the generator is executed sequentially in the order that it is defined. Our method invokes <a href="https://www.rubydoc.info/gems/thor/Thor/Actions#create_file-instance_method"><code>create_file</code></a>, which will create a file at the given destination with the given content.</p><p>To invoke our new generator, we run:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate initializer </code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate initializer ">Copy</button> </div> <p>Before we go on, let's see the description of our new generator:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate initializer <span class="nt">--help</span> </code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate initializer --help ">Copy</button> </div> <p>Rails is usually able to derive a good description if a generator is namespaced, such as <code>ActiveRecord::Generators::ModelGenerator</code>, but not in this case. We can solve this problem in two ways. The first way to add a description is by calling <a href="https://www.rubydoc.info/gems/thor/Thor#desc-class_method"><code>desc</code></a> inside our generator:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="k">class</span> <span class="nc">InitializerGenerator</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Generators</span><span class="o">::</span><span class="no">Base</span> <span class="n">desc</span> <span class="s2">"This generator creates an initializer file at config/initializers"</span> <span class="k">def</span> <span class="nf">create_initializer_file</span> <span class="n">create_file</span> <span class="s2">"config/initializers/initializer.rb"</span><span class="p">,</span> <span class="o"><<~</span><span class="no">RUBY</span><span class="sh"> # Add initialization content here </span><span class="no"> RUBY</span> <span class="k">end</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="class InitializerGenerator < Rails::Generators::Base desc "This generator creates an initializer file at config/initializers" def create_initializer_file create_file "config/initializers/initializer.rb", <<~RUBY # Add initialization content here RUBY end end ">Copy</button> </div> <p>Now we can see the new description by invoking <code>--help</code> on the new generator.</p><p>The second way to add a description is by creating a file named <code>USAGE</code> in the same directory as our generator. We are going to do that in the next step.</p><h2 id="creating-generators-with-generators"><a class="anchorlink" href="#creating-generators-with-generators" data-turbo="false"><span>3</span> Creating Generators with Generators</a></h2><p>Generators themselves have a generator. Let's remove our <code>InitializerGenerator</code> and use <code>bin/rails generate generator</code> to generate a new one:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">rm </span>lib/generators/initializer_generator.rb <span class="go"> </span><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate generator initializer <span class="go"> create lib/generators/initializer create lib/generators/initializer/initializer_generator.rb create lib/generators/initializer/USAGE create lib/generators/initializer/templates invoke test_unit create test/lib/generators/initializer_generator_test.rb </span></code></pre> <button class="clipboard-button" data-clipboard-text="rm lib/generators/initializer_generator.rb bin/rails generate generator initializer ">Copy</button> </div> <p>This is the generator just created:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="k">class</span> <span class="nc">InitializerGenerator</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Generators</span><span class="o">::</span><span class="no">NamedBase</span> <span class="n">source_root</span> <span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s2">"templates"</span><span class="p">,</span> <span class="n">__dir__</span><span class="p">)</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="class InitializerGenerator < Rails::Generators::NamedBase source_root File.expand_path("templates", __dir__) end ">Copy</button> </div> <p>First, notice that the generator inherits from <a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/NamedBase.html"><code>Rails::Generators::NamedBase</code></a> instead of <code>Rails::Generators::Base</code>. This means that our generator expects at least one argument, which will be the name of the initializer and will be available to our code via <code>name</code>.</p><p>We can see that by checking the description of the new generator:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate initializer <span class="nt">--help</span> <span class="go">Usage: bin/rails generate initializer NAME [options] </span></code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate initializer --help ">Copy</button> </div> <p>Also, notice that the generator has a class method called <a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Base.html#method-c-source_root"><code>source_root</code></a>. This method points to the location of our templates, if any. By default it points to the <code>lib/generators/initializer/templates</code> directory that was just created.</p><p>In order to understand how generator templates work, let's create the file <code>lib/generators/initializer/templates/initializer.rb</code> with the following content:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="c1"># Add initialization content here</span> </code></pre> <button class="clipboard-button" data-clipboard-text="# Add initialization content here ">Copy</button> </div> <p>And let's change the generator to copy this template when invoked:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="k">class</span> <span class="nc">InitializerGenerator</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Generators</span><span class="o">::</span><span class="no">NamedBase</span> <span class="n">source_root</span> <span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s2">"templates"</span><span class="p">,</span> <span class="n">__dir__</span><span class="p">)</span> <span class="k">def</span> <span class="nf">copy_initializer_file</span> <span class="n">copy_file</span> <span class="s2">"initializer.rb"</span><span class="p">,</span> <span class="s2">"config/initializers/</span><span class="si">#{</span><span class="n">file_name</span><span class="si">}</span><span class="s2">.rb"</span> <span class="k">end</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="class InitializerGenerator < Rails::Generators::NamedBase source_root File.expand_path("templates", __dir__) def copy_initializer_file copy_file "initializer.rb", "config/initializers/#{file_name}.rb" end end ">Copy</button> </div> <p>Now let's run our generator:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate initializer core_extensions <span class="go"> create config/initializers/core_extensions.rb </span><span class="gp">$</span><span class="w"> </span><span class="nb">cat </span>config/initializers/core_extensions.rb <span class="gp">#</span><span class="w"> </span>Add initialization content here </code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate initializer core_extensions cat config/initializers/core_extensions.rb ">Copy</button> </div> <p>We see that <a href="https://www.rubydoc.info/gems/thor/Thor/Actions#copy_file-instance_method"><code>copy_file</code></a> created <code>config/initializers/core_extensions.rb</code> with the contents of our template. (The <code>file_name</code> method used in the destination path is inherited from <code>Rails::Generators::NamedBase</code>.)</p><h2 id="generator-command-line-options"><a class="anchorlink" href="#generator-command-line-options" data-turbo="false"><span>4</span> Generator Command Line Options</a></h2><p>Generators can support command line options using <a href="https://www.rubydoc.info/gems/thor/Thor/Base/ClassMethods#class_option-instance_method"><code>class_option</code></a>. For example:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="k">class</span> <span class="nc">InitializerGenerator</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Generators</span><span class="o">::</span><span class="no">NamedBase</span> <span class="n">class_option</span> <span class="ss">:scope</span><span class="p">,</span> <span class="ss">type: :string</span><span class="p">,</span> <span class="ss">default: </span><span class="s2">"app"</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="class InitializerGenerator < Rails::Generators::NamedBase class_option :scope, type: :string, default: "app" end ">Copy</button> </div> <p>Now our generator can be invoked with a <code>--scope</code> option:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate initializer theme <span class="nt">--scope</span> dashboard </code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate initializer theme --scope dashboard ">Copy</button> </div> <p>Option values are accessible in generator methods via <a href="https://www.rubydoc.info/gems/thor/Thor/Base#options-instance_method"><code>options</code></a>:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="k">def</span> <span class="nf">copy_initializer_file</span> <span class="vi">@scope</span> <span class="o">=</span> <span class="n">options</span><span class="p">[</span><span class="s2">"scope"</span><span class="p">]</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="def copy_initializer_file @scope = options["scope"] end ">Copy</button> </div> <h2 id="generator-resolution"><a class="anchorlink" href="#generator-resolution" data-turbo="false"><span>5</span> Generator Resolution</a></h2><p>When resolving a generator's name, Rails looks for the generator using multiple file names. For example, when you run <code>bin/rails generate initializer core_extensions</code>, Rails tries to load each of the following files, in order, until one is found:</p> <ul> <li><code>rails/generators/initializer/initializer_generator.rb</code></li> <li><code>generators/initializer/initializer_generator.rb</code></li> <li><code>rails/generators/initializer_generator.rb</code></li> <li><code>generators/initializer_generator.rb</code></li> </ul> <p>If none of these are found, an error will be raised.</p><p>We put our generator in the application's <code>lib/</code> directory because that directory is in <code>$LOAD_PATH</code>, thus allowing Rails to find and load the file.</p><h2 id="overriding-rails-generator-templates"><a class="anchorlink" href="#overriding-rails-generator-templates" data-turbo="false"><span>6</span> Overriding Rails Generator Templates</a></h2><p>Rails will also look in multiple places when resolving generator template files. One of those places is the application's <code>lib/templates/</code> directory. This behavior allows us to override the templates used by Rails' built-in generators. For example, we could override the <a href="https://github.com/rails/rails/blob/main/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt">scaffold controller template</a> or the <a href="https://github.com/rails/rails/tree/main/railties/lib/rails/generators/erb/scaffold/templates">scaffold view templates</a>.</p><p>To see this in action, let's create a <code>lib/templates/erb/scaffold/index.html.erb.tt</code> file with the following contents:</p><div class="interstitial code"> <pre><code class="highlight erb"><span class="cp"><%%</span> <span class="err">@</span><span class="o"><</span><span class="sx">%= plural_table_name </span><span class="cp">%></span>.count %> <span class="cp"><%=</span><span class="sx"> human_name.pluralize </span><span class="cp">%></span> </code></pre> <button class="clipboard-button" data-clipboard-text="<%% @<%= plural_table_name %>.count %> <%= human_name.pluralize %> ">Copy</button> </div> <p>Note that the template is an ERB template that renders <em>another</em> ERB template. So any <code><%</code> that should appear in the <em>resulting</em> template must be escaped as <code><%%</code> in the <em>generator</em> template.</p><p>Now let's run Rails' built-in scaffold generator:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate scaffold Post title:string <span class="c"> ... </span><span class="go"> create app/views/posts/index.html.erb </span><span class="c"> ... </span></code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate scaffold Post title:string ">Copy</button> </div> <p>The contents of <code>app/views/posts/index.html.erb</code> is:</p><div class="interstitial code"> <pre><code class="highlight erb"><span class="cp"><%</span> <span class="vi">@posts</span><span class="p">.</span><span class="nf">count</span> <span class="cp">%></span> Posts </code></pre> <button class="clipboard-button" data-clipboard-text="<% @posts.count %> Posts ">Copy</button> </div> <h2 id="overriding-rails-generators"><a class="anchorlink" href="#overriding-rails-generators" data-turbo="false"><span>7</span> Overriding Rails Generators</a></h2><p>Rails' built-in generators can be configured via <a href="configuring.html#configuring-generators"><code>config.generators</code></a>, including overriding some generators entirely.</p><p>First, let's take a closer look at how the scaffold generator works.</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate scaffold User name:string <span class="go"> invoke active_record create db/migrate/20230518000000_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml invoke resource_route route resources :users invoke scaffold_controller create app/controllers/users_controller.rb invoke erb create app/views/users create app/views/users/index.html.erb create app/views/users/edit.html.erb create app/views/users/show.html.erb create app/views/users/new.html.erb create app/views/users/_form.html.erb create app/views/users/_user.html.erb invoke resource_route invoke test_unit create test/controllers/users_controller_test.rb create test/system/users_test.rb invoke helper create app/helpers/users_helper.rb invoke test_unit invoke jbuilder create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder </span></code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate scaffold User name:string ">Copy</button> </div> <p>From the output, we can see that the scaffold generator invokes other generators, such as the <code>scaffold_controller</code> generator. And some of those generators invoke other generators too. In particular, the <code>scaffold_controller</code> generator invokes several other generators, including the <code>helper</code> generator.</p><p>Let's override the built-in <code>helper</code> generator with a new generator. We'll name the generator <code>my_helper</code>:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate generator <span class="nb">rails</span>/my_helper <span class="go"> create lib/generators/rails/my_helper create lib/generators/rails/my_helper/my_helper_generator.rb create lib/generators/rails/my_helper/USAGE create lib/generators/rails/my_helper/templates invoke test_unit create test/lib/generators/rails/my_helper_generator_test.rb </span></code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate generator rails/my_helper ">Copy</button> </div> <p>And in <code>lib/generators/rails/my_helper/my_helper_generator.rb</code> we'll define the generator as:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="k">class</span> <span class="nc">Rails::MyHelperGenerator</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Generators</span><span class="o">::</span><span class="no">NamedBase</span> <span class="k">def</span> <span class="nf">create_helper_file</span> <span class="n">create_file</span> <span class="s2">"app/helpers/</span><span class="si">#{</span><span class="n">file_name</span><span class="si">}</span><span class="s2">_helper.rb"</span><span class="p">,</span> <span class="o"><<~</span><span class="no">RUBY</span><span class="sh"> module </span><span class="si">#{</span><span class="n">class_name</span><span class="si">}</span><span class="sh">Helper # I'm helping! end </span><span class="no"> RUBY</span> <span class="k">end</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="class Rails::MyHelperGenerator < Rails::Generators::NamedBase def create_helper_file create_file "app/helpers/#{file_name}_helper.rb", <<~RUBY module #{class_name}Helper # I'm helping! end RUBY end end ">Copy</button> </div> <p>Finally, we need to tell Rails to use the <code>my_helper</code> generator instead of the built-in <code>helper</code> generator. For that we use <code>config.generators</code>. In <code>config/application.rb</code>, let's add:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="n">config</span><span class="p">.</span><span class="nf">generators</span> <span class="k">do</span> <span class="o">|</span><span class="n">g</span><span class="o">|</span> <span class="n">g</span><span class="p">.</span><span class="nf">helper</span> <span class="ss">:my_helper</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="config.generators do |g| g.helper :my_helper end ">Copy</button> </div> <p>Now if we run the scaffold generator again, we see the <code>my_helper</code> generator in action:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate scaffold Article body:text <span class="c"> ... </span><span class="go"> invoke scaffold_controller </span><span class="c"> ... </span><span class="go"> invoke my_helper create app/helpers/articles_helper.rb </span><span class="c"> ... </span></code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate scaffold Article body:text ">Copy</button> </div> <div class="interstitial note"><p>You may notice that the output for the built-in <code>helper</code> generator includes "invoke test_unit", whereas the output for <code>my_helper</code> does not. Although the <code>helper</code> generator does not generate tests by default, it does provide a hook to do so using <a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Base.html#method-c-hook_for"><code>hook_for</code></a>. We can do the same by including <code>hook_for :test_framework, as: :helper</code> in the <code>MyHelperGenerator</code> class. See the <code>hook_for</code> documentation for more information.</p></div><h3 id="generators-fallbacks"><a class="anchorlink" href="#generators-fallbacks" data-turbo="false"><span>7.1</span> Generators Fallbacks</a></h3><p>Another way to override specific generators is by using <em>fallbacks</em>. A fallback allows a generator namespace to delegate to another generator namespace.</p><p>For example, let's say we want to override the <code>test_unit:model</code> generator with our own <code>my_test_unit:model</code> generator, but we don't want to replace all of the other <code>test_unit:*</code> generators such as <code>test_unit:controller</code>.</p><p>First, we create the <code>my_test_unit:model</code> generator in <code>lib/generators/my_test_unit/model/model_generator.rb</code>:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="k">module</span> <span class="nn">MyTestUnit</span> <span class="k">class</span> <span class="nc">ModelGenerator</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Generators</span><span class="o">::</span><span class="no">NamedBase</span> <span class="n">source_root</span> <span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s2">"templates"</span><span class="p">,</span> <span class="n">__dir__</span><span class="p">)</span> <span class="k">def</span> <span class="nf">do_different_stuff</span> <span class="n">say</span> <span class="s2">"Doing different stuff..."</span> <span class="k">end</span> <span class="k">end</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="module MyTestUnit class ModelGenerator < Rails::Generators::NamedBase source_root File.expand_path("templates", __dir__) def do_different_stuff say "Doing different stuff..." end end end ">Copy</button> </div> <p>Next, we use <code>config.generators</code> to configure the <code>test_framework</code> generator as <code>my_test_unit</code>, but we also configure a fallback such that any missing <code>my_test_unit:*</code> generators resolve to <code>test_unit:*</code>:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="n">config</span><span class="p">.</span><span class="nf">generators</span> <span class="k">do</span> <span class="o">|</span><span class="n">g</span><span class="o">|</span> <span class="n">g</span><span class="p">.</span><span class="nf">test_framework</span> <span class="ss">:my_test_unit</span><span class="p">,</span> <span class="ss">fixture: </span><span class="kp">false</span> <span class="n">g</span><span class="p">.</span><span class="nf">fallbacks</span><span class="p">[</span><span class="ss">:my_test_unit</span><span class="p">]</span> <span class="o">=</span> <span class="ss">:test_unit</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="config.generators do |g| g.test_framework :my_test_unit, fixture: false g.fallbacks[:my_test_unit] = :test_unit end ">Copy</button> </div> <p>Now when we run the scaffold generator, we see that <code>my_test_unit</code> has replaced <code>test_unit</code>, but only the model tests have been affected:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>generate scaffold Comment body:text <span class="go"> invoke active_record create db/migrate/20230518000000_create_comments.rb create app/models/comment.rb invoke my_test_unit Doing different stuff... invoke resource_route route resources :comments invoke scaffold_controller create app/controllers/comments_controller.rb invoke erb create app/views/comments create app/views/comments/index.html.erb create app/views/comments/edit.html.erb create app/views/comments/show.html.erb create app/views/comments/new.html.erb create app/views/comments/_form.html.erb create app/views/comments/_comment.html.erb invoke resource_route invoke my_test_unit create test/controllers/comments_controller_test.rb create test/system/comments_test.rb invoke helper create app/helpers/comments_helper.rb invoke my_test_unit invoke jbuilder create app/views/comments/index.json.jbuilder create app/views/comments/show.json.jbuilder </span></code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails generate scaffold Comment body:text ">Copy</button> </div> <h2 id="application-templates"><a class="anchorlink" href="#application-templates" data-turbo="false"><span>8</span> Application Templates</a></h2><p>Application templates are a special kind of generator. They can use all of the <a href="#generator-helper-methods">generator helper methods</a>, but are written as a Ruby script instead of a Ruby class. Here is an example:</p><div class="interstitial code"> <pre><code class="highlight ruby"><span class="c1"># template.rb</span> <span class="k">if</span> <span class="n">yes?</span><span class="p">(</span><span class="s2">"Would you like to install Devise?"</span><span class="p">)</span> <span class="n">gem</span> <span class="s2">"devise"</span> <span class="n">devise_model</span> <span class="o">=</span> <span class="n">ask</span><span class="p">(</span><span class="s2">"What would you like the user model to be called?"</span><span class="p">,</span> <span class="ss">default: </span><span class="s2">"User"</span><span class="p">)</span> <span class="k">end</span> <span class="n">after_bundle</span> <span class="k">do</span> <span class="k">if</span> <span class="n">devise_model</span> <span class="n">generate</span> <span class="s2">"devise:install"</span> <span class="n">generate</span> <span class="s2">"devise"</span><span class="p">,</span> <span class="n">devise_model</span> <span class="n">rails_command</span> <span class="s2">"db:migrate"</span> <span class="k">end</span> <span class="n">git</span> <span class="ss">add: </span><span class="s2">"."</span><span class="p">,</span> <span class="ss">commit: </span><span class="sx">%(-m 'Initial commit')</span> <span class="k">end</span> </code></pre> <button class="clipboard-button" data-clipboard-text="# template.rb if yes?("Would you like to install Devise?") gem "devise" devise_model = ask("What would you like the user model to be called?", default: "User") end after_bundle do if devise_model generate "devise:install" generate "devise", devise_model rails_command "db:migrate" end git add: ".", commit: %(-m 'Initial commit') end ">Copy</button> </div> <p>First, the template asks the user whether they would like to install Devise. If the user replies "yes" (or "y"), the template adds Devise to the <code>Gemfile</code>, and asks the user for the name of the Devise user model (defaulting to <code>User</code>). Later, after <code>bundle install</code> has been run, the template will run the Devise generators and <code>rails db:migrate</code> if a Devise model was specified. Finally, the template will <code>git add</code> and <code>git commit</code> the entire app directory.</p><p>We can run our template when generating a new Rails application by passing the <code>-m</code> option to the <code>rails new</code> command:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">rails </span>new my_cool_app <span class="nt">-m</span> path/to/template.rb </code></pre> <button class="clipboard-button" data-clipboard-text="rails new my_cool_app -m path/to/template.rb ">Copy</button> </div> <p>Alternatively, we can run our template inside an existing application with <code>bin/rails app:template</code>:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>app:template <span class="nv">LOCATION</span><span class="o">=</span>path/to/template.rb </code></pre> <button class="clipboard-button" data-clipboard-text="bin/rails app:template LOCATION=path/to/template.rb ">Copy</button> </div> <p>Templates also don't need to be stored locally — you can specify a URL instead of a path:</p><div class="interstitial code"> <pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">rails </span>new my_cool_app <span class="nt">-m</span> http://example.com/template.rb <span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>app:template <span class="nv">LOCATION</span><span class="o">=</span>http://example.com/template.rb </code></pre> <button class="clipboard-button" data-clipboard-text="rails new my_cool_app -m http://example.com/template.rb bin/rails app:template LOCATION=http://example.com/template.rb ">Copy</button> </div> <h2 id="generator-helper-methods"><a class="anchorlink" href="#generator-helper-methods" data-turbo="false"><span>9</span> Generator Helper Methods</a></h2><p>Thor provides many generator helper methods via <a href="https://www.rubydoc.info/gems/thor/Thor/Actions"><code>Thor::Actions</code></a>, such as:</p> <ul> <li><a href="https://www.rubydoc.info/gems/thor/Thor/Actions#copy_file-instance_method"><code>copy_file</code></a></li> <li><a href="https://www.rubydoc.info/gems/thor/Thor/Actions#create_file-instance_method"><code>create_file</code></a></li> <li><a href="https://www.rubydoc.info/gems/thor/Thor/Actions#gsub_file-instance_method"><code>gsub_file</code></a></li> <li><a href="https://www.rubydoc.info/gems/thor/Thor/Actions#insert_into_file-instance_method"><code>insert_into_file</code></a></li> <li><a href="https://www.rubydoc.info/gems/thor/Thor/Actions#inside-instance_method"><code>inside</code></a></li> </ul> <p>In addition to those, Rails also provides many helper methods via <a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html"><code>Rails::Generators::Actions</code></a>, such as:</p> <ul> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html#method-i-environment"><code>environment</code></a></li> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html#method-i-gem"><code>gem</code></a></li> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html#method-i-generate"><code>generate</code></a></li> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html#method-i-git"><code>git</code></a></li> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html#method-i-initializer"><code>initializer</code></a></li> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html#method-i-lib"><code>lib</code></a></li> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html#method-i-rails_command"><code>rails_command</code></a></li> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html#method-i-rake"><code>rake</code></a></li> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Actions.html#method-i-route"><code>route</code></a></li> </ul> <h2 id="testing-generators"><a class="anchorlink" href="#testing-generators" data-turbo="false"><span>10</span> Testing Generators</a></h2><p>Rails provides testing helper methods via <a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Testing/Behavior.html"><code>Rails::Generators::Testing::Behaviour</code></a>, such as:</p> <ul> <li><a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Testing/Behavior.html#method-i-run_generator"><code>run_generator</code></a></li> </ul> <p>If running tests against generators you will need to set <code>RAILS_LOG_TO_STDOUT=true</code> in order for debugging tools to work.</p><div class="interstitial code"> <pre><code class="highlight sh"><span class="nv">RAILS_LOG_TO_STDOUT</span><span class="o">=</span><span class="nb">true</span> ./bin/test <span class="nb">test</span>/generators/actions_test.rb </code></pre> <button class="clipboard-button" data-clipboard-text="RAILS_LOG_TO_STDOUT=true ./bin/test test/generators/actions_test.rb ">Copy</button> </div> <p>In addition to those, Rails also provides additional assertions via <a href="https://api.rubyonrails.org/v8.0.0/classes/Rails/Generators/Testing/Assertions.html"><code>Rails::Generators::Testing::Assertions</code></a>.</p> </section> <hr> <footer aria-labelledby="heading-feedback" role="region"> <h2 id="heading-feedback">Feedback</h2> <p> You're encouraged to help improve the quality of this guide. </p> <p> Please contribute if you see any typos or factual errors. To get started, you can read our <a href="https://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#contributing-to-the-rails-documentation">documentation contributions</a> section. </p> <p> You may also find incomplete content or stuff that is not up to date. Please do add any missing documentation for main. Make sure to check <a href="https://edgeguides.rubyonrails.org">Edge Guides</a> first to verify if the issues are already fixed or not on the main branch. Check the <a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a> for style and conventions. </p> <p> If for whatever reason you spot something to fix but cannot patch it yourself, please <a href="https://github.com/rails/rails/issues">open an issue</a>. </p> <p>And last but not least, any kind of discussion regarding Ruby on Rails documentation is very welcome on the <a href="https://discuss.rubyonrails.org/c/rubyonrails-docs">official Ruby on Rails Forum</a>. </p> </footer> </div> </article> </main> <hr class="hide" /> <footer id="complementary"> <div class="wrapper"> <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> <p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p> </div> </footer> <a href="#main-skip-link" class="back-to-top" data-turbo="false"><span class="visibly-hidden">Back to top</span></a> </body> </html>