railties 7.2.1 → 8.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +111 -287
 - data/lib/minitest/rails_plugin.rb +1 -1
 - data/lib/rails/application/configuration.rb +15 -2
 - data/lib/rails/application/default_middleware_stack.rb +4 -0
 - data/lib/rails/application/finisher.rb +2 -2
 - data/lib/rails/application/routes_reloader.rb +11 -1
 - data/lib/rails/application.rb +5 -0
 - data/lib/rails/code_statistics.rb +128 -86
 - data/lib/rails/code_statistics_calculator.rb +78 -76
 - data/lib/rails/command/helpers/editor.rb +1 -1
 - data/lib/rails/commands/app/update_command.rb +1 -9
 - data/lib/rails/commands/credentials/USAGE +4 -4
 - data/lib/rails/commands/credentials/credentials_command.rb +5 -1
 - data/lib/rails/commands/dev/dev_command.rb +1 -1
 - data/lib/rails/commands/devcontainer/devcontainer_command.rb +1 -1
 - data/lib/rails/commands/stats/stats_command.rb +19 -0
 - data/lib/rails/dev_caching.rb +2 -2
 - data/lib/rails/engine/configuration.rb +3 -1
 - data/lib/rails/engine/lazy_route_set.rb +109 -0
 - data/lib/rails/engine.rb +10 -5
 - data/lib/rails/gem_version.rb +4 -4
 - data/lib/rails/generators/app_base.rb +46 -24
 - data/lib/rails/generators/database.rb +101 -67
 - data/lib/rails/generators/erb/authentication/authentication_generator.rb +15 -0
 - data/lib/rails/generators/erb/authentication/templates/views/passwords/edit.html.erb +9 -0
 - data/lib/rails/generators/erb/authentication/templates/views/passwords/new.html.erb +8 -0
 - data/lib/rails/generators/erb/authentication/templates/views/sessions/new.html.erb +11 -0
 - data/lib/rails/generators/generated_attribute.rb +16 -11
 - data/lib/rails/generators/rails/app/app_generator.rb +19 -32
 - data/lib/rails/generators/rails/app/templates/Dockerfile.tt +12 -3
 - data/lib/rails/generators/rails/app/templates/Gemfile.tt +23 -8
 - data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt +6 -11
 - data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +10 -3
 - data/lib/rails/generators/rails/app/templates/bin/dev.tt +1 -0
 - data/lib/rails/generators/rails/app/templates/bin/setup.tt +5 -7
 - data/lib/rails/generators/rails/app/templates/bin/thrust.tt +4 -0
 - data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +23 -0
 - data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +23 -0
 - data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +40 -0
 - data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +23 -0
 - data/lib/rails/generators/rails/app/templates/config/deploy.yml.tt +124 -0
 - data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +12 -23
 - data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +34 -51
 - data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -19
 - data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +0 -7
 - data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
 - data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_0.rb.tt +25 -0
 - data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +11 -2
 - data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +3 -3
 - data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +4 -3
 - data/lib/rails/generators/rails/app/templates/dockerignore.tt +1 -2
 - data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +1 -1
 - data/lib/rails/generators/rails/app/templates/gitignore.tt +1 -2
 - data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +17 -0
 - data/lib/rails/generators/rails/app/templates/public/400.html +114 -0
 - data/lib/rails/generators/rails/app/templates/public/404.html +113 -66
 - data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +113 -65
 - data/lib/rails/generators/rails/app/templates/public/422.html +113 -66
 - data/lib/rails/generators/rails/app/templates/public/500.html +113 -65
 - data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
 - data/lib/rails/generators/rails/app/templates/public/icon.svg +2 -2
 - data/lib/rails/generators/rails/authentication/USAGE +6 -0
 - data/lib/rails/generators/rails/authentication/authentication_generator.rb +54 -0
 - data/lib/rails/generators/rails/authentication/templates/controllers/concerns/authentication.rb +55 -0
 - data/lib/rails/generators/rails/authentication/templates/controllers/passwords_controller.rb +33 -0
 - data/lib/rails/generators/rails/authentication/templates/controllers/sessions_controller.rb +21 -0
 - data/lib/rails/generators/rails/authentication/templates/mailers/passwords_mailer.rb +6 -0
 - data/lib/rails/generators/rails/authentication/templates/models/current.rb +4 -0
 - data/lib/rails/generators/rails/authentication/templates/models/session.rb +3 -0
 - data/lib/rails/generators/rails/authentication/templates/models/user.rb +6 -0
 - data/lib/rails/generators/rails/authentication/templates/test/mailers/previews/passwords_mailer_preview.rb +7 -0
 - data/lib/rails/generators/rails/authentication/templates/views/passwords_mailer/reset.html.erb +4 -0
 - data/lib/rails/generators/rails/authentication/templates/views/passwords_mailer/reset.text.erb +2 -0
 - data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +4 -0
 - data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
 - data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +5 -3
 - data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +1 -1
 - data/lib/rails/generators/rails/plugin/plugin_generator.rb +11 -11
 - data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +1 -1
 - data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -2
 - data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +2 -2
 - data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +3 -3
 - data/lib/rails/generators/rails/script/USAGE +18 -0
 - data/lib/rails/generators/rails/script/script_generator.rb +18 -0
 - data/lib/rails/generators/rails/script/templates/script.rb.tt +3 -0
 - data/lib/rails/generators.rb +7 -2
 - data/lib/rails/info_controller.rb +10 -2
 - data/lib/rails/rack/silence_request.rb +33 -0
 - data/lib/rails/rack.rb +1 -0
 - data/lib/rails/railtie.rb +13 -13
 - data/lib/rails/source_annotation_extractor.rb +31 -14
 - data/lib/rails/tasks/statistics.rake +13 -28
 - data/lib/rails/templates/rails/info/notes.html.erb +65 -0
 - metadata +45 -25
 - data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -2
 - data/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb.tt +0 -4
 - data/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb.tt +0 -4
 - data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +0 -70
 - data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +0 -13
 - data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +0 -13
 - data/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js.tt +0 -10
 - data/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js.tt +0 -6
 - data/lib/rails/generators/rails/plugin/templates/rails/javascripts.js.tt +0 -17
 
| 
         @@ -1,66 +1,114 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            <! 
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            < 
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
              < 
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
                 
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            <!doctype html>
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            <html lang="en">
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              <head>
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                <title>We’re sorry, but something went wrong (500 Internal Server Error)</title>
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                <meta charset="utf-8">
         
     | 
| 
      
 10 
     | 
    
         
            +
                <meta name="viewport" content="initial-scale=1, width=device-width">
         
     | 
| 
      
 11 
     | 
    
         
            +
                <meta name="robots" content="noindex, nofollow">
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                <style>
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  *, *::before, *::after {
         
     | 
| 
      
 16 
     | 
    
         
            +
                    box-sizing: border-box;
         
     | 
| 
      
 17 
     | 
    
         
            +
                  }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  * {
         
     | 
| 
      
 20 
     | 
    
         
            +
                    margin: 0;
         
     | 
| 
      
 21 
     | 
    
         
            +
                  }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  html {
         
     | 
| 
      
 24 
     | 
    
         
            +
                    font-size: 16px;
         
     | 
| 
      
 25 
     | 
    
         
            +
                  }
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  body {
         
     | 
| 
      
 28 
     | 
    
         
            +
                    background: #FFF;
         
     | 
| 
      
 29 
     | 
    
         
            +
                    color: #261B23;
         
     | 
| 
      
 30 
     | 
    
         
            +
                    display: grid;
         
     | 
| 
      
 31 
     | 
    
         
            +
                    font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Aptos, Roboto, "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
         
     | 
| 
      
 32 
     | 
    
         
            +
                    font-size: clamp(1rem, 2.5vw, 2rem);
         
     | 
| 
      
 33 
     | 
    
         
            +
                    -webkit-font-smoothing: antialiased;
         
     | 
| 
      
 34 
     | 
    
         
            +
                    font-style: normal;
         
     | 
| 
      
 35 
     | 
    
         
            +
                    font-weight: 400;
         
     | 
| 
      
 36 
     | 
    
         
            +
                    letter-spacing: -0.0025em;
         
     | 
| 
      
 37 
     | 
    
         
            +
                    line-height: 1.4;
         
     | 
| 
      
 38 
     | 
    
         
            +
                    min-height: 100vh;
         
     | 
| 
      
 39 
     | 
    
         
            +
                    place-items: center;
         
     | 
| 
      
 40 
     | 
    
         
            +
                    text-rendering: optimizeLegibility;
         
     | 
| 
      
 41 
     | 
    
         
            +
                    -webkit-text-size-adjust: 100%;
         
     | 
| 
      
 42 
     | 
    
         
            +
                  }
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  a {
         
     | 
| 
      
 45 
     | 
    
         
            +
                    color: inherit;
         
     | 
| 
      
 46 
     | 
    
         
            +
                    font-weight: 700;
         
     | 
| 
      
 47 
     | 
    
         
            +
                    text-decoration: underline;
         
     | 
| 
      
 48 
     | 
    
         
            +
                    text-underline-offset: 0.0925em;
         
     | 
| 
      
 49 
     | 
    
         
            +
                  }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  b, strong {
         
     | 
| 
      
 52 
     | 
    
         
            +
                    font-weight: 700;
         
     | 
| 
      
 53 
     | 
    
         
            +
                  }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  i, em {
         
     | 
| 
      
 56 
     | 
    
         
            +
                    font-style: italic;
         
     | 
| 
      
 57 
     | 
    
         
            +
                  }
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  main {
         
     | 
| 
      
 60 
     | 
    
         
            +
                    display: grid;
         
     | 
| 
      
 61 
     | 
    
         
            +
                    gap: 1em;
         
     | 
| 
      
 62 
     | 
    
         
            +
                    padding: 2em;
         
     | 
| 
      
 63 
     | 
    
         
            +
                    place-items: center;
         
     | 
| 
      
 64 
     | 
    
         
            +
                    text-align: center;
         
     | 
| 
      
 65 
     | 
    
         
            +
                  }
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  main header {
         
     | 
| 
      
 68 
     | 
    
         
            +
                    width: min(100%, 12em);
         
     | 
| 
      
 69 
     | 
    
         
            +
                  }
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  main header svg {
         
     | 
| 
      
 72 
     | 
    
         
            +
                    height: auto;
         
     | 
| 
      
 73 
     | 
    
         
            +
                    max-width: 100%;
         
     | 
| 
      
 74 
     | 
    
         
            +
                    width: 100%;
         
     | 
| 
      
 75 
     | 
    
         
            +
                  }
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  main article {
         
     | 
| 
      
 78 
     | 
    
         
            +
                    width: min(100%, 30em);
         
     | 
| 
      
 79 
     | 
    
         
            +
                  }
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  main article p {
         
     | 
| 
      
 82 
     | 
    
         
            +
                    font-size: 75%;
         
     | 
| 
      
 83 
     | 
    
         
            +
                  }
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                  main article br {
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                    display: none;
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                    @media(min-width: 48em) {
         
     | 
| 
      
 90 
     | 
    
         
            +
                      display: inline;
         
     | 
| 
      
 91 
     | 
    
         
            +
                    }
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  }
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                </style>
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
              </head>
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
              <body>
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                <!-- This file lives in public/500.html -->
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                <main>
         
     | 
| 
      
 104 
     | 
    
         
            +
                  <header>
         
     | 
| 
      
 105 
     | 
    
         
            +
                    <svg height="172" viewBox="0 0 480 172" width="480" xmlns="http://www.w3.org/2000/svg"><path d="m101.23 93.8427c-8.1103 0-15.4098 3.7849-19.7354 8.3813h-36.2269v-99.21891h103.8143v37.03791h-68.3984v24.8722c5.1366-2.7035 15.1396-5.9477 24.6014-5.9477 35.146 0 56.233 22.7094 56.233 55.4215 0 34.605-23.791 57.315-60.558 57.315-37.8492 0-61.64-22.169-63.8028-55.963h42.9857c1.0814 10.814 9.1919 19.195 21.6281 19.195 11.355 0 19.465-8.381 19.465-20.547 0-11.625-7.299-20.5463-20.006-20.5463zm138.833 77.8613c-40.822 0-64.884-35.146-64.884-85.7015 0-50.5554 24.062-85.700907 64.884-85.700907 40.823 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.061 85.7015-64.884 85.7015zm0-133.2831c-17.572 0-22.709 21.8984-22.709 47.5816 0 25.6835 5.137 47.5815 22.709 47.5815 17.303 0 22.71-21.898 22.71-47.5815 0-25.6832-5.407-47.5816-22.71-47.5816zm140.456 133.2831c-40.823 0-64.884-35.146-64.884-85.7015 0-50.5554 24.061-85.700907 64.884-85.700907 40.822 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.062 85.7015-64.884 85.7015zm0-133.2831c-17.573 0-22.71 21.8984-22.71 47.5816 0 25.6835 5.137 47.5815 22.71 47.5815 17.302 0 22.709-21.898 22.709-47.5815 0-25.6832-5.407-47.5816-22.709-47.5816z" fill="#f0eff0"/><path d="m23.1377 68.9967v34.0033h-8.9162v-34.0033zm4.3157 34.0033v-24.921h8.6947v2.1598c1.3845-1.5506 3.8212-2.7136 6.701-2.7136 5.538 0 8.8054 3.5997 8.8054 9.1377v16.3371h-8.6393v-14.2327c0-2.049-1.0522-3.5443-3.2674-3.5443-1.7168 0-3.1567.9969-3.5997 2.7136v15.0634zm29.9913-8.5839v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.5839v6.8671h5.2058v6.7564h-5.2058v8.307c0 1.9383.9415 2.769 2.6583 2.769.9414 0 1.9937-.2216 2.769-.5538v7.3654c-.9969.443-2.8798.775-4.8181.775-5.8703 0-9.1931-2.769-9.1931-9.0819zm32.3666-.1108h8.0301c-.8861 5.7597-5.2057 9.2487-11.6852 9.2487-7.6424 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.3165-13.0143 12.5159-13.0143 7.6424 0 11.9621 5.095 11.9621 12.5159v2.1598h-16.1156c.2769 2.9905 1.8275 4.5965 4.3196 4.5965 1.7722 0 3.1567-.7753 3.6551-2.4921zm-3.8212-10.0237c-2.0491 0-3.4336 1.2737-3.9874 3.5997h7.5317c-.1107-2.0491-1.3845-3.5997-3.5443-3.5997zm31.4299-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.599-.7753-2.382 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.381.443zm2.949 25.0318v-24.921h8.694v2.1598c1.385-1.5506 3.821-2.7136 6.701-2.7136 5.538 0 8.806 3.5997 8.806 9.1377v16.3371h-8.64v-14.2327c0-2.049-1.052-3.5443-3.267-3.5443-1.717 0-3.157.9969-3.6 2.7136v15.0634zm50.371 0h-8.363v-1.274c-.83.831-3.323 1.717-5.981 1.717-4.929 0-9.082-2.769-9.082-8.0301 0-4.818 4.153-7.9193 9.581-7.9193 2.049 0 4.485.6646 5.482 1.3845v-1.606c0-1.606-.941-2.9905-3.046-2.9905-1.606 0-2.547.7199-2.935 1.8275h-8.196c.72-4.8181 4.984-8.6393 11.408-8.6393 7.089 0 11.132 3.7659 11.132 10.2453zm-8.363-6.9779v-1.4399c-.554-1.0522-2.049-1.7167-3.655-1.7167-1.717 0-3.433.7199-3.433 2.3813 0 1.7168 1.716 2.4367 3.433 2.4367 1.606 0 3.101-.6645 3.655-1.6614zm20.742-29.0191v35.997h-8.694v-35.997zm13.036 25.9178h9.248c.72 2.326 2.714 3.489 5.483 3.489 2.713 0 4.596-1.163 4.596-3.2674 0-1.6061-1.052-2.326-3.212-2.8244l-6.534-1.3845c-4.985-1.1076-8.751-3.7105-8.751-9.47 0-6.6456 5.538-11.0206 13.07-11.0206 8.307 0 13.014 4.5411 13.956 10.4114h-8.695c-.72-1.8829-2.27-3.3228-5.205-3.3228-2.548 0-4.265 1.1076-4.265 2.9905 0 1.4953 1.052 2.326 2.825 2.7137l6.645 1.5506c5.815 1.3845 9.027 4.5412 9.027 9.8023 0 6.9778-5.87 10.9654-13.291 10.9654-8.141 0-13.679-3.9322-14.897-10.6332zm46.509 1.3845h8.031c-.887 5.7597-5.206 9.2487-11.686 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.317-13.0143 12.516-13.0143 7.643 0 11.962 5.095 11.962 12.5159v2.1598h-16.115c.277 2.9905 1.827 4.5965 4.319 4.5965 1.773 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm31.431-6.3134v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.382.443zm18.288 25.0318h-7.809l-9.47-24.921h8.861l4.763 14.288 4.652-14.288h8.528zm25.614-8.6947h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.516-13.0143 7.642 0 11.962 5.095 11.962 12.5159v2.1598h-16.116c.277 2.9905 1.828 4.5965 4.32 4.5965 1.772 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.434 1.2737-3.988 3.5997h7.532c-.111-2.0491-1.384-3.5997-3.544-3.5997zm31.43-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443zm13.703-8.9715h24.312v7.6424h-15.562v5.3165h14.232v7.4763h-14.232v5.8703h15.562v7.6978h-24.312zm44.667 8.9715v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm19.673 0v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm26.769 12.5713c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.529 0c0-3.4336-1.495-5.8703-4.208-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.208-2.3813 4.208-5.8149zm28.082-12.5713v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443z" fill="#d30001"/></svg>
         
     | 
| 
      
 106 
     | 
    
         
            +
                  </header>
         
     | 
| 
      
 107 
     | 
    
         
            +
                  <article>
         
     | 
| 
      
 108 
     | 
    
         
            +
                    <p><strong>We’re sorry, but something went wrong.</strong><br> If you’re the application owner check the logs for more information.</p>
         
     | 
| 
      
 109 
     | 
    
         
            +
                  </article>
         
     | 
| 
      
 110 
     | 
    
         
            +
                </main>
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
              </body>
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
       66 
114 
     | 
    
         
             
            </html>
         
     | 
| 
         Binary file 
     | 
| 
         @@ -1,3 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            <svg width=" 
     | 
| 
       2 
     | 
    
         
            -
              < 
     | 
| 
      
 1 
     | 
    
         
            +
            <svg width="512" height="512" xmlns="http://www.w3.org/2000/svg">
         
     | 
| 
      
 2 
     | 
    
         
            +
              <circle cx="256" cy="256" r="256" fill="red"/>
         
     | 
| 
       3 
3 
     | 
    
         
             
            </svg>
         
     | 
| 
         @@ -0,0 +1,54 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Rails
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Generators
         
     | 
| 
      
 5 
     | 
    
         
            +
                class AuthenticationGenerator < Base # :nodoc:
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class_option :api, type: :boolean,
         
     | 
| 
      
 7 
     | 
    
         
            +
                    desc: "Generate API-only controllers and models, with no view templates"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  hook_for :template_engine, as: :authentication do |template_engine|
         
     | 
| 
      
 10 
     | 
    
         
            +
                    invoke template_engine unless options.api?
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def create_authentication_files
         
     | 
| 
      
 14 
     | 
    
         
            +
                    template "models/session.rb", File.join("app/models/session.rb")
         
     | 
| 
      
 15 
     | 
    
         
            +
                    template "models/user.rb", File.join("app/models/user.rb")
         
     | 
| 
      
 16 
     | 
    
         
            +
                    template "models/current.rb", File.join("app/models/current.rb")
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    template "controllers/sessions_controller.rb", File.join("app/controllers/sessions_controller.rb")
         
     | 
| 
      
 19 
     | 
    
         
            +
                    template "controllers/concerns/authentication.rb", File.join("app/controllers/concerns/authentication.rb")
         
     | 
| 
      
 20 
     | 
    
         
            +
                    template "controllers/passwords_controller.rb", File.join("app/controllers/passwords_controller.rb")
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    template "mailers/passwords_mailer.rb", File.join("app/mailers/passwords_mailer.rb")
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    template "views/passwords_mailer/reset.html.erb", File.join("app/views/passwords_mailer/reset.html.erb")
         
     | 
| 
      
 25 
     | 
    
         
            +
                    template "views/passwords_mailer/reset.text.erb", File.join("app/views/passwords_mailer/reset.text.erb")
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    template "test/mailers/previews/passwords_mailer_preview.rb", File.join("test/mailers/previews/passwords_mailer_preview.rb")
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def configure_application_controller
         
     | 
| 
      
 31 
     | 
    
         
            +
                    gsub_file "app/controllers/application_controller.rb", /(class ApplicationController < ActionController::Base)/, "\\1\n  include Authentication"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def configure_authentication_routes
         
     | 
| 
      
 35 
     | 
    
         
            +
                    route "resources :passwords, param: :token"
         
     | 
| 
      
 36 
     | 
    
         
            +
                    route "resource :session"
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  def enable_bcrypt
         
     | 
| 
      
 40 
     | 
    
         
            +
                    if File.read("Gemfile").include?('gem "bcrypt"')
         
     | 
| 
      
 41 
     | 
    
         
            +
                      uncomment_lines "Gemfile", /gem "bcrypt"/
         
     | 
| 
      
 42 
     | 
    
         
            +
                      Bundler.with_original_env { execute_command :bundle, "install --quiet" }
         
     | 
| 
      
 43 
     | 
    
         
            +
                    else
         
     | 
| 
      
 44 
     | 
    
         
            +
                      Bundler.with_original_env { execute_command :bundle, "add bcrypt --quiet" }
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def add_migrations
         
     | 
| 
      
 49 
     | 
    
         
            +
                    generate "migration CreateUsers email_address:string!:uniq password_digest:string! --force"
         
     | 
| 
      
 50 
     | 
    
         
            +
                    generate "migration CreateSessions user:references ip_address:string user_agent:string --force"
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/rails/generators/rails/authentication/templates/controllers/concerns/authentication.rb
    ADDED
    
    | 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Authentication
         
     | 
| 
      
 2 
     | 
    
         
            +
              extend ActiveSupport::Concern
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              included do
         
     | 
| 
      
 5 
     | 
    
         
            +
                before_action :require_authentication
         
     | 
| 
      
 6 
     | 
    
         
            +
                helper_method :authenticated?
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              class_methods do
         
     | 
| 
      
 10 
     | 
    
         
            +
                def allow_unauthenticated_access(**options)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  skip_before_action :require_authentication, **options
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              private
         
     | 
| 
      
 16 
     | 
    
         
            +
                def authenticated?
         
     | 
| 
      
 17 
     | 
    
         
            +
                  Current.session.present?
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def require_authentication
         
     | 
| 
      
 21 
     | 
    
         
            +
                  resume_session || request_authentication
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def resume_session
         
     | 
| 
      
 26 
     | 
    
         
            +
                  Current.session = find_session_by_cookie
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def find_session_by_cookie
         
     | 
| 
      
 30 
     | 
    
         
            +
                  Session.find_by(id: cookies.signed[:session_id])
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def request_authentication
         
     | 
| 
      
 35 
     | 
    
         
            +
                  session[:return_to_after_authenticating] = request.url
         
     | 
| 
      
 36 
     | 
    
         
            +
                  redirect_to new_session_url
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def after_authentication_url
         
     | 
| 
      
 40 
     | 
    
         
            +
                  session.delete(:return_to_after_authenticating) || root_url
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def start_new_session_for(user)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  user.sessions.create!(user_agent: request.user_agent, ip_address: request.remote_ip).tap do |session|
         
     | 
| 
      
 46 
     | 
    
         
            +
                    Current.session = session
         
     | 
| 
      
 47 
     | 
    
         
            +
                    cookies.signed.permanent[:session_id] = { value: session.id, httponly: true, same_site: :lax }
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def terminate_session
         
     | 
| 
      
 52 
     | 
    
         
            +
                  Current.session.destroy
         
     | 
| 
      
 53 
     | 
    
         
            +
                  cookies.delete(:session_id)
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class PasswordsController < ApplicationController
         
     | 
| 
      
 2 
     | 
    
         
            +
              allow_unauthenticated_access
         
     | 
| 
      
 3 
     | 
    
         
            +
              before_action :set_user_by_token, only: %i[ edit update ]
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def new
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def create
         
     | 
| 
      
 9 
     | 
    
         
            +
                if user = User.find_by(email_address: params[:email_address])
         
     | 
| 
      
 10 
     | 
    
         
            +
                  PasswordsMailer.reset(user).deliver_later
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                redirect_to new_session_url, notice: "Password reset instructions sent (if user with that email address exists)."
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              def edit
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def update
         
     | 
| 
      
 20 
     | 
    
         
            +
                if @user.update(params.permit(:password, :password_confirmation))
         
     | 
| 
      
 21 
     | 
    
         
            +
                  redirect_to new_session_url, notice: "Password has been reset."
         
     | 
| 
      
 22 
     | 
    
         
            +
                else
         
     | 
| 
      
 23 
     | 
    
         
            +
                  redirect_to edit_password_url(params[:token]), alert: "Passwords did not match."
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              private
         
     | 
| 
      
 28 
     | 
    
         
            +
                def set_user_by_token
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @user = User.find_by_password_reset_token!(params[:token])
         
     | 
| 
      
 30 
     | 
    
         
            +
                rescue ActiveSupport::MessageVerifier::InvalidSignature
         
     | 
| 
      
 31 
     | 
    
         
            +
                  redirect_to new_password_url, alert: "Password reset link is invalid or has expired."
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class SessionsController < ApplicationController
         
     | 
| 
      
 2 
     | 
    
         
            +
              allow_unauthenticated_access only: %i[ new create ]
         
     | 
| 
      
 3 
     | 
    
         
            +
              rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to new_session_url, alert: "Try again later." }
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def new
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def create
         
     | 
| 
      
 9 
     | 
    
         
            +
                if user = User.authenticate_by(params.permit(:email_address, :password))
         
     | 
| 
      
 10 
     | 
    
         
            +
                  start_new_session_for user
         
     | 
| 
      
 11 
     | 
    
         
            +
                  redirect_to after_authentication_url
         
     | 
| 
      
 12 
     | 
    
         
            +
                else
         
     | 
| 
      
 13 
     | 
    
         
            +
                  redirect_to new_session_url, alert: "Try another email address or password."
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def destroy
         
     | 
| 
      
 18 
     | 
    
         
            +
                terminate_session
         
     | 
| 
      
 19 
     | 
    
         
            +
                redirect_to new_session_url
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Preview all emails at http://localhost:3000/rails/mailers/passwords_mailer
         
     | 
| 
      
 2 
     | 
    
         
            +
            class PasswordsMailerPreview < ActionMailer::Preview
         
     | 
| 
      
 3 
     | 
    
         
            +
              # Preview this email at http://localhost:3000/rails/mailers/passwords_mailer/reset
         
     | 
| 
      
 4 
     | 
    
         
            +
              def reset
         
     | 
| 
      
 5 
     | 
    
         
            +
                PasswordsMailer.reset(User.take)
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -38,9 +38,11 @@ module Rails 
     | 
|
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
                  def update_application_system_test_case
         
     | 
| 
       40 
40 
     | 
    
         
             
                    return unless options[:system_test]
         
     | 
| 
       41 
     | 
    
         
            -
                    return unless File.exist?("test/application_system_test_case.rb")
         
     | 
| 
       42 
41 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                     
     | 
| 
      
 42 
     | 
    
         
            +
                    system_test_case_path = File.expand_path "test/application_system_test_case.rb", destination_root
         
     | 
| 
      
 43 
     | 
    
         
            +
                    return unless File.exist? system_test_case_path
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                    gsub_file(system_test_case_path, /^\s*driven_by\b.*/, system_test_configuration)
         
     | 
| 
       44 
46 
     | 
    
         
             
                  end
         
     | 
| 
       45 
47 
     | 
    
         | 
| 
       46 
48 
     | 
    
         
             
                  def update_database_yml
         
     | 
| 
         @@ -148,7 +150,7 @@ module Rails 
     | 
|
| 
       148 
150 
     | 
    
         
             
                    end
         
     | 
| 
       149 
151 
     | 
    
         | 
| 
       150 
152 
     | 
    
         
             
                    def system_test_configuration
         
     | 
| 
       151 
     | 
    
         
            -
                      optimize_indentation(<<-'RUBY', 2)
         
     | 
| 
      
 153 
     | 
    
         
            +
                      optimize_indentation(<<-'RUBY', 2).chomp
         
     | 
| 
       152 
154 
     | 
    
         
             
                        if ENV["CAPYBARA_SERVER_PORT"]
         
     | 
| 
       153 
155 
     | 
    
         
             
                          served_by host: "rails-app", port: ENV["CAPYBARA_SERVER_PORT"]
         
     | 
| 
       154 
156 
     | 
    
         | 
| 
         @@ -122,9 +122,12 @@ module Rails 
     | 
|
| 
       122 
122 
     | 
    
         
             
                def generate_test_dummy(force = false)
         
     | 
| 
       123 
123 
     | 
    
         
             
                  opts = options.transform_keys(&:to_sym).except(*DUMMY_IGNORE_OPTIONS)
         
     | 
| 
       124 
124 
     | 
    
         
             
                  opts[:force] = force
         
     | 
| 
      
 125 
     | 
    
         
            +
                  opts[:skip_thruster] = true
         
     | 
| 
       125 
126 
     | 
    
         
             
                  opts[:skip_brakeman] = true
         
     | 
| 
       126 
127 
     | 
    
         
             
                  opts[:skip_bundle] = true
         
     | 
| 
       127 
128 
     | 
    
         
             
                  opts[:skip_ci] = true
         
     | 
| 
      
 129 
     | 
    
         
            +
                  opts[:skip_kamal] = true
         
     | 
| 
      
 130 
     | 
    
         
            +
                  opts[:skip_solid] = true
         
     | 
| 
       128 
131 
     | 
    
         
             
                  opts[:skip_git] = true
         
     | 
| 
       129 
132 
     | 
    
         
             
                  opts[:skip_hotwire] = true
         
     | 
| 
       130 
133 
     | 
    
         
             
                  opts[:skip_rubocop] = true
         
     | 
| 
         @@ -149,9 +152,8 @@ module Rails 
     | 
|
| 
       149 
152 
     | 
    
         
             
                  end
         
     | 
| 
       150 
153 
     | 
    
         
             
                end
         
     | 
| 
       151 
154 
     | 
    
         | 
| 
       152 
     | 
    
         
            -
                def  
     | 
| 
       153 
     | 
    
         
            -
                  template "rails/stylesheets.css", 
     | 
| 
       154 
     | 
    
         
            -
                  template "rails/dummy_manifest.js", "#{dummy_path}/app/assets/config/manifest.js", force: true
         
     | 
| 
      
 155 
     | 
    
         
            +
                def test_dummy_assets
         
     | 
| 
      
 156 
     | 
    
         
            +
                  template "rails/stylesheets.css", "#{dummy_path}/app/assets/stylesheets/application.css", force: true
         
     | 
| 
       155 
157 
     | 
    
         
             
                end
         
     | 
| 
       156 
158 
     | 
    
         | 
| 
       157 
159 
     | 
    
         
             
                def test_dummy_clean
         
     | 
| 
         @@ -159,7 +161,7 @@ module Rails 
     | 
|
| 
       159 
161 
     | 
    
         
             
                    remove_file ".ruby-version"
         
     | 
| 
       160 
162 
     | 
    
         
             
                    remove_dir "db"
         
     | 
| 
       161 
163 
     | 
    
         
             
                    remove_file "Gemfile"
         
     | 
| 
       162 
     | 
    
         
            -
                     
     | 
| 
      
 164 
     | 
    
         
            +
                    remove_dir "lib"
         
     | 
| 
       163 
165 
     | 
    
         
             
                    remove_file "public/robots.txt"
         
     | 
| 
       164 
166 
     | 
    
         
             
                    remove_file "README.md"
         
     | 
| 
       165 
167 
     | 
    
         
             
                    remove_file "test"
         
     | 
| 
         @@ -167,10 +169,6 @@ module Rails 
     | 
|
| 
       167 
169 
     | 
    
         
             
                  end
         
     | 
| 
       168 
170 
     | 
    
         
             
                end
         
     | 
| 
       169 
171 
     | 
    
         | 
| 
       170 
     | 
    
         
            -
                def assets_manifest
         
     | 
| 
       171 
     | 
    
         
            -
                  template "rails/engine_manifest.js", "app/assets/config/#{underscored_name}_manifest.js"
         
     | 
| 
       172 
     | 
    
         
            -
                end
         
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
172 
     | 
    
         
             
                def stylesheets
         
     | 
| 
       175 
173 
     | 
    
         
             
                  if mountable?
         
     | 
| 
       176 
174 
     | 
    
         
             
                    copy_file "rails/stylesheets.css",
         
     | 
| 
         @@ -361,7 +359,7 @@ module Rails 
     | 
|
| 
       361 
359 
     | 
    
         
             
                    mute do
         
     | 
| 
       362 
360 
     | 
    
         
             
                      build(:generate_test_dummy)
         
     | 
| 
       363 
361 
     | 
    
         
             
                      build(:test_dummy_config)
         
     | 
| 
       364 
     | 
    
         
            -
                      build(: 
     | 
| 
      
 362 
     | 
    
         
            +
                      build(:test_dummy_assets) unless skip_asset_pipeline?
         
     | 
| 
       365 
363 
     | 
    
         
             
                      build(:test_dummy_clean)
         
     | 
| 
       366 
364 
     | 
    
         
             
                      # ensure that bin/rails has proper dummy_path
         
     | 
| 
       367 
365 
     | 
    
         
             
                      build(:bin)
         
     | 
| 
         @@ -491,9 +489,11 @@ module Rails 
     | 
|
| 
       491 
489 
     | 
    
         | 
| 
       492 
490 
     | 
    
         
             
                  def test_command
         
     | 
| 
       493 
491 
     | 
    
         
             
                    if engine? && !options[:skip_active_record] && with_dummy_app?
         
     | 
| 
       494 
     | 
    
         
            -
                      "db:test:prepare test"
         
     | 
| 
      
 492 
     | 
    
         
            +
                      "bin/rails db:test:prepare test"
         
     | 
| 
      
 493 
     | 
    
         
            +
                    elsif engine?
         
     | 
| 
      
 494 
     | 
    
         
            +
                      "bin/rails test"
         
     | 
| 
       495 
495 
     | 
    
         
             
                    else
         
     | 
| 
       496 
     | 
    
         
            -
                      "test"
         
     | 
| 
      
 496 
     | 
    
         
            +
                      "bin/test"
         
     | 
| 
       497 
497 
     | 
    
         
             
                    end
         
     | 
| 
       498 
498 
     | 
    
         
             
                  end
         
     | 
| 
       499 
499 
     | 
    
         
             
                end
         
     | 
| 
         @@ -90,7 +90,7 @@ jobs: 
     | 
|
| 
       90 
90 
     | 
    
         
             
                      DATABASE_URL: postgres://postgres:postgres@localhost:5432
         
     | 
| 
       91 
91 
     | 
    
         
             
                      <%- end -%>
         
     | 
| 
       92 
92 
     | 
    
         
             
                      # REDIS_URL: redis://localhost:6379/0
         
     | 
| 
       93 
     | 
    
         
            -
                    run:  
     | 
| 
      
 93 
     | 
    
         
            +
                    run: <%= test_command %>
         
     | 
| 
       94 
94 
     | 
    
         | 
| 
       95 
95 
     | 
    
         
             
                  - name: Keep screenshots from failed system tests
         
     | 
| 
       96 
96 
     | 
    
         
             
                    uses: actions/upload-artifact@v4
         
     | 
| 
         @@ -3,7 +3,7 @@ ENV["RAILS_ENV"] = "test" 
     | 
|
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            require_relative "<%= File.join("..", options[:dummy_path], "config/environment") -%>"
         
     | 
| 
       5 
5 
     | 
    
         
             
            <% unless options[:skip_active_record] -%>
         
     | 
| 
       6 
     | 
    
         
            -
            ActiveRecord::Migrator.migrations_paths = [File.expand_path("../<%= options[:dummy_path] -%>/db/migrate", __dir__)]
         
     | 
| 
      
 6 
     | 
    
         
            +
            ActiveRecord::Migrator.migrations_paths = [ File.expand_path("../<%= options[:dummy_path] -%>/db/migrate", __dir__) ]
         
     | 
| 
       7 
7 
     | 
    
         
             
            <% if options[:mountable] -%>
         
     | 
| 
       8 
8 
     | 
    
         
             
            ActiveRecord::Migrator.migrations_paths << File.expand_path("../db/migrate", __dir__)
         
     | 
| 
       9 
9 
     | 
    
         
             
            <% end -%>
         
     | 
| 
         @@ -13,7 +13,7 @@ require "rails/test_help" 
     | 
|
| 
       13 
13 
     | 
    
         
             
            <% unless options[:skip_active_record] -%>
         
     | 
| 
       14 
14 
     | 
    
         
             
            # Load fixtures from the engine
         
     | 
| 
       15 
15 
     | 
    
         
             
            if ActiveSupport::TestCase.respond_to?(:fixture_paths=)
         
     | 
| 
       16 
     | 
    
         
            -
              ActiveSupport::TestCase.fixture_paths = [File.expand_path("fixtures", __dir__)]
         
     | 
| 
      
 16 
     | 
    
         
            +
              ActiveSupport::TestCase.fixture_paths = [ File.expand_path("fixtures", __dir__) ]
         
     | 
| 
       17 
17 
     | 
    
         
             
              ActionDispatch::IntegrationTest.fixture_paths = ActiveSupport::TestCase.fixture_paths
         
     | 
| 
       18 
18 
     | 
    
         
             
              ActiveSupport::TestCase.file_fixture_path = File.expand_path("fixtures", __dir__) + "/files"
         
     | 
| 
       19 
19 
     | 
    
         
             
              ActiveSupport::TestCase.fixtures :all
         
     | 
| 
         @@ -42,7 +42,7 @@ class <%= controller_class_name %>Controller < ApplicationController 
     | 
|
| 
       42 
42 
     | 
    
         
             
              private
         
     | 
| 
       43 
43 
     | 
    
         
             
                # Use callbacks to share common setup or constraints between actions.
         
     | 
| 
       44 
44 
     | 
    
         
             
                def set_<%= singular_table_name %>
         
     | 
| 
       45 
     | 
    
         
            -
                  @<%= singular_table_name %> = <%= orm_class.find(class_name, "params 
     | 
| 
      
 45 
     | 
    
         
            +
                  @<%= singular_table_name %> = <%= orm_class.find(class_name, "params.expect(:id)") %>
         
     | 
| 
       46 
46 
     | 
    
         
             
                end
         
     | 
| 
       47 
47 
     | 
    
         | 
| 
       48 
48 
     | 
    
         
             
                # Only allow a list of trusted parameters through.
         
     | 
| 
         @@ -50,7 +50,7 @@ class <%= controller_class_name %>Controller < ApplicationController 
     | 
|
| 
       50 
50 
     | 
    
         
             
                  <%- if attributes_names.empty? -%>
         
     | 
| 
       51 
51 
     | 
    
         
             
                  params.fetch(:<%= singular_table_name %>, {})
         
     | 
| 
       52 
52 
     | 
    
         
             
                  <%- else -%>
         
     | 
| 
       53 
     | 
    
         
            -
                  params. 
     | 
| 
      
 53 
     | 
    
         
            +
                  params.expect(<%= singular_table_name %>: [ <%= permitted_params %> ])
         
     | 
| 
       54 
54 
     | 
    
         
             
                  <%- end -%>
         
     | 
| 
       55 
55 
     | 
    
         
             
                end
         
     | 
| 
       56 
56 
     | 
    
         
             
            end
         
     | 
| 
         @@ -43,13 +43,13 @@ class <%= controller_class_name %>Controller < ApplicationController 
     | 
|
| 
       43 
43 
     | 
    
         
             
              # DELETE <%= route_url %>/1
         
     | 
| 
       44 
44 
     | 
    
         
             
              def destroy
         
     | 
| 
       45 
45 
     | 
    
         
             
                @<%= orm_instance.destroy %>
         
     | 
| 
       46 
     | 
    
         
            -
                redirect_to <%= index_helper %> 
     | 
| 
      
 46 
     | 
    
         
            +
                redirect_to <%= index_helper %>_path, notice: <%= %("#{human_name} was successfully destroyed.") %>, status: :see_other
         
     | 
| 
       47 
47 
     | 
    
         
             
              end
         
     | 
| 
       48 
48 
     | 
    
         | 
| 
       49 
49 
     | 
    
         
             
              private
         
     | 
| 
       50 
50 
     | 
    
         
             
                # Use callbacks to share common setup or constraints between actions.
         
     | 
| 
       51 
51 
     | 
    
         
             
                def set_<%= singular_table_name %>
         
     | 
| 
       52 
     | 
    
         
            -
                  @<%= singular_table_name %> = <%= orm_class.find(class_name, "params 
     | 
| 
      
 52 
     | 
    
         
            +
                  @<%= singular_table_name %> = <%= orm_class.find(class_name, "params.expect(:id)") %>
         
     | 
| 
       53 
53 
     | 
    
         
             
                end
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         
             
                # Only allow a list of trusted parameters through.
         
     | 
| 
         @@ -57,7 +57,7 @@ class <%= controller_class_name %>Controller < ApplicationController 
     | 
|
| 
       57 
57 
     | 
    
         
             
                  <%- if attributes_names.empty? -%>
         
     | 
| 
       58 
58 
     | 
    
         
             
                  params.fetch(:<%= singular_table_name %>, {})
         
     | 
| 
       59 
59 
     | 
    
         
             
                  <%- else -%>
         
     | 
| 
       60 
     | 
    
         
            -
                  params. 
     | 
| 
      
 60 
     | 
    
         
            +
                  params.expect(<%= singular_table_name %>: [ <%= permitted_params %> ])
         
     | 
| 
       61 
61 
     | 
    
         
             
                  <%- end -%>
         
     | 
| 
       62 
62 
     | 
    
         
             
                end
         
     | 
| 
       63 
63 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Description:
         
     | 
| 
      
 2 
     | 
    
         
            +
                Generate a one-off or general purpose script, such as a data migration
         
     | 
| 
      
 3 
     | 
    
         
            +
                script, cleanup script, etc.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Example:
         
     | 
| 
      
 6 
     | 
    
         
            +
                `bin/rails generate script my_script`
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                This will create:
         
     | 
| 
      
 9 
     | 
    
         
            +
                    script/my_script.rb
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                You can run the script using:
         
     | 
| 
      
 12 
     | 
    
         
            +
                    `ruby script/my_script.rb`
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                You can specify a folder:
         
     | 
| 
      
 15 
     | 
    
         
            +
                    `bin/rails generate script cleanup/my_script`
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                This will create:
         
     | 
| 
      
 18 
     | 
    
         
            +
                    script/cleanup/my_script.rb
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "rails/generators/named_base"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Rails
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Generators
         
     | 
| 
      
 7 
     | 
    
         
            +
                class ScriptGenerator < NamedBase
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def generate_script
         
     | 
| 
      
 9 
     | 
    
         
            +
                    template("script.rb.tt", "script/#{file_path}.rb")
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  private
         
     | 
| 
      
 13 
     | 
    
         
            +
                    def depth
         
     | 
| 
      
 14 
     | 
    
         
            +
                      class_path.size + 1
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     |