aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/lib/rails/generators/css/scaffold/scaffold_generator.rb6
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb8
-rw-r--r--railties/lib/rails/generators/named_base.rb35
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/update.tt5
-rw-r--r--railties/lib/rails/generators/rails/master_key/master_key_generator.rb26
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb4
-rw-r--r--railties/test/application/middleware/cookies_test.rb60
-rw-r--r--railties/test/fixtures/about_yml_plugins/bad_about_yml/about.yml1
-rw-r--r--railties/test/fixtures/about_yml_plugins/bad_about_yml/init.rb3
-rw-r--r--railties/test/fixtures/about_yml_plugins/plugin_without_about_yml/init.rb3
-rw-r--r--railties/test/generators/app_generator_test.rb7
-rw-r--r--railties/test/generators/named_base_test.rb13
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb23
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