diff options
Diffstat (limited to 'railties')
15 files changed, 136 insertions, 66 deletions
diff --git a/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb index 5996cb1483..d8eb4f2c7b 100644 --- a/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb @@ -5,13 +5,13 @@ require_relative "../../named_base"  module Css # :nodoc:    module Generators # :nodoc:      class ScaffoldGenerator < Rails::Generators::NamedBase # :nodoc: +      source_root Rails::Generators::ScaffoldGenerator.source_root +        # In order to allow the Sass generators to pick up the default Rails CSS and        # transform it, we leave it in a standard location for the CSS stylesheet        # generators to handle. For the simple, default case, just copy it over.        def copy_stylesheet -        dir = Rails::Generators::ScaffoldGenerator.source_root -        file = File.join(dir, "scaffold.css") -        create_file "app/assets/stylesheets/scaffold.css", File.read(file) +        copy_file "scaffold.css", "app/assets/stylesheets/scaffold.css"        end      end    end diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb index 4f2e84f924..0eb9d82bbb 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb @@ -1,4 +1,4 @@ -<%%= form_with(model: <%= singular_table_name %>, local: true) do |form| %> +<%%= form_with(model: <%= model_resource_name %>, local: true) do |form| %>    <%% if <%= singular_table_name %>.errors.any? %>      <div id="error_explanation">        <h2><%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2> diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb index 5f4904fee1..e1ede7c713 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb @@ -18,9 +18,9 @@  <% attributes.reject(&:password_digest?).each do |attribute| -%>          <td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>  <% end -%> -        <td><%%= link_to 'Show', <%= singular_table_name %> %></td> -        <td><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %></td> -        <td><%%= link_to 'Destroy', <%= singular_table_name %>, method: :delete, data: { confirm: 'Are you sure?' } %></td> +        <td><%%= link_to 'Show', <%= model_resource_name %> %></td> +        <td><%%= link_to 'Edit', edit_<%= singular_route_name %>_path(<%= singular_table_name %>) %></td> +        <td><%%= link_to 'Destroy', <%= model_resource_name %>, method: :delete, data: { confirm: 'Are you sure?' } %></td>        </tr>      <%% end %>    </tbody> @@ -28,4 +28,4 @@  <br> -<%%= link_to 'New <%= singular_table_name.titleize %>', new_<%= singular_table_name %>_path %> +<%%= link_to 'New <%= singular_table_name.titleize %>', new_<%= singular_route_name %>_path %> diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index fe8447be23..5f602f1d52 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -100,11 +100,11 @@ module Rails          end          def index_helper # :doc: -          uncountable? ? "#{plural_table_name}_index" : plural_table_name +          uncountable? ? "#{plural_route_name}_index" : plural_route_name          end          def show_helper # :doc: -          "#{singular_table_name}_url(@#{singular_table_name})" +          "#{singular_route_name}_url(@#{singular_table_name})"          end          def edit_helper # :doc: @@ -112,7 +112,7 @@ module Rails          end          def new_helper # :doc: -          "new_#{singular_table_name}_url" +          "new_#{singular_route_name}_url"          end          def field_id(attribute_name) @@ -152,6 +152,35 @@ module Rails            end          end +        def redirect_resource_name # :doc: +          model_resource_name(prefix: "@") +        end + +        def model_resource_name(prefix: "") # :doc: +          resource_name = "#{prefix}#{singular_table_name}" +          if controller_class_path.empty? +            resource_name +          else +            "[#{controller_class_path.map { |name| ":" + name }.join(", ")}, #{resource_name}]" +          end +        end + +        def singular_route_name # :doc: +          if controller_class_path.empty? +            singular_table_name +          else +            "#{controller_class_path.join('_')}_#{singular_table_name}" +          end +        end + +        def plural_route_name # :doc: +          if controller_class_path.empty? +            plural_table_name +          else +            "#{controller_class_path.join('_')}_#{plural_table_name}" +          end +        end +          def assign_names!(name)            @class_path = name.include?("/") ? name.split("/") : name.split("::")            @class_path.map!(&:underscore) diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index ac82ff6633..23fdf03b05 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -69,7 +69,7 @@ module Rails      def version_control        if !options[:skip_git] && !options[:pretend] -        run "git init" +        run "git init", capture: options[:quiet]        end      end @@ -164,7 +164,7 @@ module Rails        require_relative "../master_key/master_key_generator"        after_bundle do -        Rails::Generators::MasterKeyGenerator.new.add_master_key_file +        Rails::Generators::MasterKeyGenerator.new([], quiet: options[:quiet]).add_master_key_file        end      end @@ -174,7 +174,7 @@ module Rails        require_relative "../credentials/credentials_generator"        after_bundle do -        Rails::Generators::CredentialsGenerator.new.add_credentials_file_silently +        Rails::Generators::CredentialsGenerator.new([], quiet: options[:quiet]).add_credentials_file_silently        end      end diff --git a/railties/lib/rails/generators/rails/app/templates/bin/update.tt b/railties/lib/rails/generators/rails/app/templates/bin/update.tt index d744bec32f..70cc71d83b 100644 --- a/railties/lib/rails/generators/rails/app/templates/bin/update.tt +++ b/railties/lib/rails/generators/rails/app/templates/bin/update.tt @@ -15,6 +15,11 @@ chdir APP_ROOT do    puts '== Installing dependencies =='    system! 'gem install bundler --conservative'    system('bundle check') || system!('bundle install') +<% unless options.skip_yarn? -%> + +  # Install JavaScript dependencies if using Yarn +  # system('bin/yarn') +<% end -%>  <% unless options.skip_active_record? -%>    puts "\n== Updating database ==" diff --git a/railties/lib/rails/generators/rails/master_key/master_key_generator.rb b/railties/lib/rails/generators/rails/master_key/master_key_generator.rb index e49d3b39e0..395687974a 100644 --- a/railties/lib/rails/generators/rails/master_key/master_key_generator.rb +++ b/railties/lib/rails/generators/rails/master_key/master_key_generator.rb @@ -13,15 +13,15 @@ module Rails          unless MASTER_KEY_PATH.exist?            key = ActiveSupport::EncryptedFile.generate_key -          say "Adding #{MASTER_KEY_PATH} to store the master encryption key: #{key}" -          say "" -          say "Save this in a password manager your team can access." -          say "" -          say "If you lose the key, no one, including you, can access anything encrypted with it." +          log "Adding #{MASTER_KEY_PATH} to store the master encryption key: #{key}" +          log "" +          log "Save this in a password manager your team can access." +          log "" +          log "If you lose the key, no one, including you, can access anything encrypted with it." -          say "" +          log ""            create_file MASTER_KEY_PATH, key -          say "" +          log ""            ignore_master_key_file          end @@ -31,15 +31,15 @@ module Rails          def ignore_master_key_file            if File.exist?(".gitignore")              unless File.read(".gitignore").include?(key_ignore) -              say "Ignoring #{MASTER_KEY_PATH} so it won't end up in Git history:" -              say "" +              log "Ignoring #{MASTER_KEY_PATH} so it won't end up in Git history:" +              log ""                append_to_file ".gitignore", key_ignore -              say "" +              log ""              end            else -            say "IMPORTANT: Don't commit #{MASTER_KEY_PATH}. Add this to your ignore file:" -            say key_ignore, :on_green -            say "" +            log "IMPORTANT: Don't commit #{MASTER_KEY_PATH}. Add this to your ignore file:" +            log key_ignore, :on_green +            log ""            end          end diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb index 42b9e34274..05f1c2b2d3 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb @@ -29,7 +29,7 @@ class <%= controller_class_name %>Controller < ApplicationController      @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>      if @<%= orm_instance.save %> -      redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %> +      redirect_to <%= redirect_resource_name %>, notice: <%= "'#{human_name} was successfully created.'" %>      else        render :new      end @@ -38,7 +38,7 @@ class <%= controller_class_name %>Controller < ApplicationController    # PATCH/PUT <%= route_url %>/1    def update      if @<%= orm_instance.update("#{singular_table_name}_params") %> -      redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %> +      redirect_to <%= redirect_resource_name %>, notice: <%= "'#{human_name} was successfully updated.'" %>      else        render :edit      end diff --git a/railties/test/application/middleware/cookies_test.rb b/railties/test/application/middleware/cookies_test.rb index 932a6d0e77..ecb4ee3446 100644 --- a/railties/test/application/middleware/cookies_test.rb +++ b/railties/test/application/middleware/cookies_test.rb @@ -52,12 +52,6 @@ module ApplicationTests      end      test "signed cookies with SHA512 digest and rotated out SHA256 and SHA1 digests" do -      key_gen_sha1 = ActiveSupport::KeyGenerator.new("legacy sha1 secret", iterations: 1000) -      key_gen_sha256 = ActiveSupport::KeyGenerator.new("legacy sha256 secret", iterations: 1000) - -      verifer_sha1 = ActiveSupport::MessageVerifier.new(key_gen_sha1.generate_key("sha1 salt"), digest: :SHA1) -      verifer_sha256 = ActiveSupport::MessageVerifier.new(key_gen_sha256.generate_key("sha256 salt"), digest: :SHA256) -        app_file "config/routes.rb", <<-RUBY          Rails.application.routes.draw do            get  ':controller(/:action)' @@ -70,12 +64,12 @@ module ApplicationTests            protect_from_forgery with: :null_session            def write_raw_cookie_sha1 -            cookies[:signed_cookie] = "#{verifer_sha1.generate("signed cookie")}" +            cookies[:signed_cookie] = TestVerifiers.sha1.generate("signed cookie")              head :ok            end            def write_raw_cookie_sha256 -            cookies[:signed_cookie] = "#{verifer_sha256.generate("signed cookie")}" +            cookies[:signed_cookie] = TestVerifiers.sha256.generate("signed cookie")              head :ok            end @@ -90,42 +84,43 @@ module ApplicationTests        RUBY        add_to_config <<-RUBY -        config.action_dispatch.cookies_rotations.rotate :signed, -          digest: "SHA1", secret: "legacy sha1 secret", salt: "sha1 salt" +        sha1_secret   = Rails.application.key_generator.generate_key("sha1") +        sha256_secret = Rails.application.key_generator.generate_key("sha256") -        config.action_dispatch.cookies_rotations.rotate :signed, -          digest: "SHA256", secret: "legacy sha256 secret", salt: "sha256 salt" +        ::TestVerifiers = Class.new do +          class_attribute :sha1, default: ActiveSupport::MessageVerifier.new(sha1_secret, digest: "SHA1") +          class_attribute :sha256, default: ActiveSupport::MessageVerifier.new(sha256_secret, digest: "SHA256") +        end          config.action_dispatch.signed_cookie_digest = "SHA512"          config.action_dispatch.signed_cookie_salt = "sha512 salt" + +        config.action_dispatch.cookies_rotations.tap do |cookies| +          cookies.rotate :signed, sha1_secret,   digest: "SHA1" +          cookies.rotate :signed, sha256_secret, digest: "SHA256" +        end        RUBY        require "#{app_path}/config/environment" -      verifer_sha512 = ActiveSupport::MessageVerifier.new(app.key_generator.generate_key("sha512 salt"), digest: :SHA512) +      verifier_sha512 = ActiveSupport::MessageVerifier.new(app.key_generator.generate_key("sha512 salt"), digest: :SHA512)        get "/foo/write_raw_cookie_sha1"        get "/foo/read_signed"        assert_equal "signed cookie".inspect, last_response.body        get "/foo/read_raw_cookie" -      assert_equal "signed cookie", verifer_sha512.verify(last_response.body) +      assert_equal "signed cookie", verifier_sha512.verify(last_response.body)        get "/foo/write_raw_cookie_sha256"        get "/foo/read_signed"        assert_equal "signed cookie".inspect, last_response.body        get "/foo/read_raw_cookie" -      assert_equal "signed cookie", verifer_sha512.verify(last_response.body) +      assert_equal "signed cookie", verifier_sha512.verify(last_response.body)      end -    test "encrypted cookies with multiple rotated out ciphers" do -      key_gen_one = ActiveSupport::KeyGenerator.new("legacy secret one", iterations: 1000) -      key_gen_two = ActiveSupport::KeyGenerator.new("legacy secret two", iterations: 1000) - -      encryptor_one = ActiveSupport::MessageEncryptor.new(key_gen_one.generate_key("salt one", 32), cipher: "aes-256-gcm") -      encryptor_two = ActiveSupport::MessageEncryptor.new(key_gen_two.generate_key("salt two", 32), cipher: "aes-256-gcm") - +    test "encrypted cookies rotating multiple encryption keys" do        app_file "config/routes.rb", <<-RUBY          Rails.application.routes.draw do            get  ':controller(/:action)' @@ -138,12 +133,12 @@ module ApplicationTests            protect_from_forgery with: :null_session            def write_raw_cookie_one -            cookies[:encrypted_cookie] = "#{encryptor_one.encrypt_and_sign("encrypted cookie")}" +            cookies[:encrypted_cookie] = TestEncryptors.first_gcm.encrypt_and_sign("encrypted cookie")              head :ok            end            def write_raw_cookie_two -            cookies[:encrypted_cookie] = "#{encryptor_two.encrypt_and_sign("encrypted cookie")}" +            cookies[:encrypted_cookie] = TestEncryptors.second_gcm.encrypt_and_sign("encrypted cookie")              head :ok            end @@ -158,15 +153,22 @@ module ApplicationTests        RUBY        add_to_config <<-RUBY +        first_secret  = Rails.application.key_generator.generate_key("first", 32) +        second_secret = Rails.application.key_generator.generate_key("second", 32) + +        ::TestEncryptors = Class.new do +          class_attribute :first_gcm,  default: ActiveSupport::MessageEncryptor.new(first_secret, cipher: "aes-256-gcm") +          class_attribute :second_gcm, default: ActiveSupport::MessageEncryptor.new(second_secret, cipher: "aes-256-gcm") +        end +          config.action_dispatch.use_authenticated_cookie_encryption = true          config.action_dispatch.encrypted_cookie_cipher = "aes-256-gcm"          config.action_dispatch.authenticated_encrypted_cookie_salt = "salt" -        config.action_dispatch.cookies_rotations.rotate :encrypted, -          cipher: "aes-256-gcm", secret: "legacy secret one", salt: "salt one" - -        config.action_dispatch.cookies_rotations.rotate :encrypted, -          cipher: "aes-256-gcm", secret: "legacy secret two", salt: "salt two" +        config.action_dispatch.cookies_rotations.tap do |cookies| +          cookies.rotate :encrypted, first_secret +          cookies.rotate :encrypted, second_secret +        end        RUBY        require "#{app_path}/config/environment" diff --git a/railties/test/fixtures/about_yml_plugins/bad_about_yml/about.yml b/railties/test/fixtures/about_yml_plugins/bad_about_yml/about.yml deleted file mode 100644 index fe80872a16..0000000000 --- a/railties/test/fixtures/about_yml_plugins/bad_about_yml/about.yml +++ /dev/null @@ -1 +0,0 @@ -# an empty YAML file - any content in here seems to get parsed as a string
\ No newline at end of file diff --git a/railties/test/fixtures/about_yml_plugins/bad_about_yml/init.rb b/railties/test/fixtures/about_yml_plugins/bad_about_yml/init.rb deleted file mode 100644 index 1a82a2bdd4..0000000000 --- a/railties/test/fixtures/about_yml_plugins/bad_about_yml/init.rb +++ /dev/null @@ -1,3 +0,0 @@ -# frozen_string_literal: true - -# intentionally empty diff --git a/railties/test/fixtures/about_yml_plugins/plugin_without_about_yml/init.rb b/railties/test/fixtures/about_yml_plugins/plugin_without_about_yml/init.rb deleted file mode 100644 index 1a82a2bdd4..0000000000 --- a/railties/test/fixtures/about_yml_plugins/plugin_without_about_yml/init.rb +++ /dev/null @@ -1,3 +0,0 @@ -# frozen_string_literal: true - -# intentionally empty diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 904e2a5c84..20f593f25c 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -560,6 +560,11 @@ class AppGeneratorTest < Rails::Generators::TestCase      assert_no_match(/run  git init/, output)    end +  def test_quiet_option +    output = run_generator [File.join(destination_root, "myapp"), "--quiet"] +    assert_empty output +  end +    def test_application_name_with_spaces      path = File.join(destination_root, "foo bar") @@ -737,7 +742,7 @@ class AppGeneratorTest < Rails::Generators::TestCase      sequence = ["git init", "install", "exec spring binstub --all", "echo ran after_bundle"]      @sequence_step ||= 0 -    ensure_bundler_first = -> command do +    ensure_bundler_first = -> command, options = nil do        assert_equal sequence[@sequence_step], command, "commands should be called in sequence #{sequence}"        @sequence_step += 1      end diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb index 67f05926e3..64e9909859 100644 --- a/railties/test/generators/named_base_test.rb +++ b/railties/test/generators/named_base_test.rb @@ -131,6 +131,19 @@ class NamedBaseTest < Rails::Generators::TestCase      assert_name g, "admin/foos",  :controller_file_path      assert_name g, "foos",        :controller_file_name      assert_name g, "admin.foos",  :controller_i18n_scope +    assert_name g, "admin_user",  :singular_route_name +    assert_name g, "admin_users", :plural_route_name +    assert_name g, "[:admin, @user]", :redirect_resource_name +    assert_name g, "[:admin, user]",  :model_resource_name +    assert_name g, "admin_users", :index_helper +  end + +  def test_scaffold_plural_names +    g = generator ["User"] +    assert_name g, "@user", :redirect_resource_name +    assert_name g, "user",  :model_resource_name +    assert_name g, "user",  :singular_route_name +    assert_name g, "users", :plural_route_name    end    private diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 384524aba9..513b037043 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -174,6 +174,29 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase        assert_instance_method :index, content do |m|          assert_match("@users = User.all", m)        end + +      assert_instance_method :create, content do |m| +        assert_match("redirect_to [:admin, @user]", m) +      end + +      assert_instance_method :update, content do |m| +        assert_match("redirect_to [:admin, @user]", m) +      end +    end + +    assert_file "app/views/admin/users/index.html.erb" do |content| +      assert_match("'Show', [:admin, user]", content) +      assert_match("'Edit', edit_admin_user_path(user)", content) +      assert_match("'Destroy', [:admin, user]", content) +      assert_match("'New User', new_admin_user_path", content) +    end + +    assert_file "app/views/admin/users/new.html.erb" do |content| +      assert_match("'Back', admin_users_path", content) +    end + +    assert_file "app/views/admin/users/_form.html.erb" do |content| +      assert_match("model: [:admin, user]", content)      end    end  | 
