railties 6.0.0.beta3 → 6.0.0.rc1

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -7
  3. data/RDOC_MAIN.rdoc +3 -3
  4. data/README.rdoc +1 -1
  5. data/lib/rails/application.rb +3 -1
  6. data/lib/rails/application/configuration.rb +27 -1
  7. data/lib/rails/application/default_middleware_stack.rb +1 -0
  8. data/lib/rails/application/dummy_erb_compiler.rb +19 -0
  9. data/lib/rails/application/finisher.rb +38 -1
  10. data/lib/rails/autoloaders.rb +10 -2
  11. data/lib/rails/command/environment_argument.rb +7 -4
  12. data/lib/rails/commands/console/console_command.rb +6 -0
  13. data/lib/rails/commands/credentials/USAGE +1 -1
  14. data/lib/rails/commands/credentials/credentials_command.rb +17 -3
  15. data/lib/rails/commands/dbconsole/dbconsole_command.rb +19 -7
  16. data/lib/rails/commands/dev/dev_command.rb +4 -2
  17. data/lib/rails/commands/encrypted/USAGE +28 -0
  18. data/lib/rails/commands/encrypted/encrypted_command.rb +1 -0
  19. data/lib/rails/commands/initializers/initializers_command.rb +7 -0
  20. data/lib/rails/commands/notes/notes_command.rb +1 -1
  21. data/lib/rails/commands/runner/runner_command.rb +7 -3
  22. data/lib/rails/commands/server/server_command.rb +8 -6
  23. data/lib/rails/engine.rb +27 -31
  24. data/lib/rails/gem_version.rb +1 -1
  25. data/lib/rails/generators.rb +2 -0
  26. data/lib/rails/generators/app_base.rb +2 -2
  27. data/lib/rails/generators/app_name.rb +2 -2
  28. data/lib/rails/generators/database.rb +1 -1
  29. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt +6 -3
  30. data/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt +8 -0
  31. data/lib/rails/generators/generated_attribute.rb +36 -10
  32. data/lib/rails/generators/named_base.rb +1 -0
  33. data/lib/rails/generators/rails/app/templates/Gemfile.tt +3 -3
  34. data/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt +8 -0
  35. data/lib/rails/generators/rails/app/templates/bin/setup.tt +3 -2
  36. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +2 -0
  37. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +2 -0
  38. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +10 -5
  39. data/lib/rails/generators/rails/app/templates/ruby-version.tt +1 -1
  40. data/lib/rails/generators/rails/assets/assets_generator.rb +7 -0
  41. data/lib/rails/generators/rails/db/system/change/change_generator.rb +12 -2
  42. data/lib/rails/generators/rails/plugin/plugin_generator.rb +0 -15
  43. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +8 -0
  44. data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +1 -1
  45. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +1 -1
  46. data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +2 -2
  47. data/lib/rails/mailers_controller.rb +6 -3
  48. data/lib/rails/source_annotation_extractor.rb +14 -1
  49. data/lib/rails/tasks.rb +1 -0
  50. data/lib/rails/tasks/zeitwerk.rake +78 -0
  51. metadata +14 -12
  52. data/lib/rails/generators/rails/app/templates/bin/update.tt +0 -33
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/deprecation"
4
+ require "active_support/core_ext/string/filters"
3
5
  require "rails/command/environment_argument"
4
6
 
5
7
  module Rails
@@ -89,15 +91,15 @@ module Rails
89
91
 
90
92
  def config
91
93
  @config ||= begin
92
- # We need to check whether the user passed the connection the
94
+ # We need to check whether the user passed the database the
93
95
  # first time around to show a consistent error message to people
94
96
  # relying on 2-level database configuration.
95
- if @options["connection"] && configurations[connection].blank?
96
- raise ActiveRecord::AdapterNotSpecified, "'#{connection}' connection is not configured. Available configuration: #{configurations.inspect}"
97
- elsif configurations[environment].blank? && configurations[connection].blank?
97
+ if @options["database"] && configurations[database].blank?
98
+ raise ActiveRecord::AdapterNotSpecified, "'#{database}' database is not configured. Available configuration: #{configurations.inspect}"
99
+ elsif configurations[environment].blank? && configurations[database].blank?
98
100
  raise ActiveRecord::AdapterNotSpecified, "'#{environment}' database is not configured. Available configuration: #{configurations.inspect}"
99
101
  else
100
- configurations[connection] || configurations[environment].presence
102
+ configurations[database] || configurations[environment].presence
101
103
  end
102
104
  end
103
105
  end
@@ -106,8 +108,8 @@ module Rails
106
108
  Rails.respond_to?(:env) ? Rails.env : Rails::Command.environment
107
109
  end
108
110
 
109
- def connection
110
- @options.fetch(:connection, "primary")
111
+ def database
112
+ @options.fetch(:database, "primary")
111
113
  end
112
114
 
113
115
  private
@@ -156,12 +158,22 @@ module Rails
156
158
  class_option :connection, aliases: "-c", type: :string,
157
159
  desc: "Specifies the connection to use."
158
160
 
161
+ class_option :database, aliases: "--db", type: :string,
162
+ desc: "Specifies the database to use."
163
+
159
164
  def perform
160
165
  extract_environment_option_from_argument
161
166
 
162
167
  # RAILS_ENV needs to be set before config/application is required.
163
168
  ENV["RAILS_ENV"] = options[:environment]
164
169
 
170
+ if options["connection"]
171
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
172
+ `connection` option is deprecated and will be removed in Rails 6.1. Please use `database` option instead.
173
+ MSG
174
+ options["database"] = options["connection"]
175
+ end
176
+
165
177
  require_application_and_environment!
166
178
  Rails::DBConsole.start(options)
167
179
  end
@@ -5,8 +5,10 @@ require "rails/dev_caching"
5
5
  module Rails
6
6
  module Command
7
7
  class DevCommand < Base # :nodoc:
8
- def help
9
- say "rails dev:cache # Toggle development mode caching on/off."
8
+ no_commands do
9
+ def help
10
+ say "rails dev:cache # Toggle development mode caching on/off."
11
+ end
10
12
  end
11
13
 
12
14
  def cache
@@ -0,0 +1,28 @@
1
+ === Storing Encrypted Files in Source Control
2
+
3
+ The Rails `encrypted` commands provide access to encrypted files or configurations.
4
+ See the `Rails.application.encrypted` documentation for using them in your app.
5
+
6
+ === Encryption Keys
7
+
8
+ By default, Rails looks for the encryption key in `config/master.key` or
9
+ `ENV["RAILS_MASTER_KEY"]`, but that lookup can be overridden with `--key`:
10
+
11
+ rails encrypted:edit config/encrypted_file.yml.enc --key config/encrypted_file.key
12
+
13
+ Don't commit the key! Add it to your source control's ignore file. If you use
14
+ Git, Rails handles this for you.
15
+
16
+ === Editing Files
17
+
18
+ To edit or create an encrypted file use:
19
+
20
+ rails encrypted:edit config/encrypted_file.yml.enc
21
+
22
+ This opens a temporary file in `$EDITOR` with the decrypted contents for editing.
23
+
24
+ === Viewing Files
25
+
26
+ To print the decrypted contents of an encrypted file use:
27
+
28
+ rails encrypted:show config/encrypted_file.yml.enc
@@ -16,6 +16,7 @@ module Rails
16
16
  def help
17
17
  say "Usage:\n #{self.class.banner}"
18
18
  say ""
19
+ say self.class.desc
19
20
  end
20
21
  end
21
22
 
@@ -1,10 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "rails/command/environment_argument"
4
+
3
5
  module Rails
4
6
  module Command
5
7
  class InitializersCommand < Base # :nodoc:
8
+ include EnvironmentArgument
9
+
6
10
  desc "initializers", "Print out all defined initializers in the order they are invoked by Rails."
7
11
  def perform
12
+ extract_environment_option_from_argument
13
+ ENV["RAILS_ENV"] = options[:environment]
14
+
8
15
  require_application_and_environment!
9
16
 
10
17
  Rails.application.initializers.tsort_each do |initializer|
@@ -5,7 +5,7 @@ require "rails/source_annotation_extractor"
5
5
  module Rails
6
6
  module Command
7
7
  class NotesCommand < Base # :nodoc:
8
- class_option :annotations, aliases: "-a", desc: "Filter by specific annotations, e.g. Foobar TODO", type: :array, default: %w(OPTIMIZE FIXME TODO)
8
+ class_option :annotations, aliases: "-a", desc: "Filter by specific annotations, e.g. Foobar TODO", type: :array, default: Rails::SourceAnnotationExtractor::Annotation.tags
9
9
 
10
10
  def perform(*)
11
11
  require_application_and_environment!
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "rails/command/environment_argument"
4
+
3
5
  module Rails
4
6
  module Command
5
7
  class RunnerCommand < Base # :nodoc:
6
- class_option :environment, aliases: "-e", type: :string,
7
- default: Rails::Command.environment.dup,
8
- desc: "The environment for the runner to operate under (test/development/production)"
8
+ include EnvironmentArgument
9
+
10
+ self.environment_desc = "The environment for the runner to operate under (test/development/production)"
9
11
 
10
12
  no_commands do
11
13
  def help
@@ -19,6 +21,8 @@ module Rails
19
21
  end
20
22
 
21
23
  def perform(code_or_file = nil, *command_argv)
24
+ extract_environment_option_from_argument
25
+
22
26
  unless code_or_file
23
27
  help
24
28
  exit 1
@@ -6,6 +6,7 @@ require "rails"
6
6
  require "active_support/deprecation"
7
7
  require "active_support/core_ext/string/filters"
8
8
  require "rails/dev_caching"
9
+ require "rails/command/environment_argument"
9
10
 
10
11
  module Rails
11
12
  class Server < ::Rack::Server
@@ -91,6 +92,8 @@ module Rails
91
92
 
92
93
  module Command
93
94
  class ServerCommand < Base # :nodoc:
95
+ include EnvironmentArgument
96
+
94
97
  # Hard-coding a bunch of handlers here as we don't have a public way of
95
98
  # querying them from the Rack::Handler registry.
96
99
  RACK_SERVERS = %w(cgi fastcgi webrick lsws scgi thin puma unicorn)
@@ -109,8 +112,6 @@ module Rails
109
112
  desc: "Uses a custom rackup configuration.", banner: :file
110
113
  class_option :daemon, aliases: "-d", type: :boolean, default: false,
111
114
  desc: "Runs server as a Daemon."
112
- class_option :environment, aliases: "-e", type: :string,
113
- desc: "Specifies the environment to run this server under (development/test/production).", banner: :name
114
115
  class_option :using, aliases: "-u", type: :string,
115
116
  desc: "Specifies the Rack server used to run the application (thin/puma/webrick).", banner: :name
116
117
  class_option :pid, aliases: "-P", type: :string, default: DEFAULT_PID_PATH,
@@ -130,6 +131,7 @@ module Rails
130
131
  end
131
132
 
132
133
  def perform
134
+ extract_environment_option_from_argument
133
135
  set_application_directory!
134
136
  prepare_restart
135
137
 
@@ -221,8 +223,8 @@ module Rails
221
223
 
222
224
  if ENV["HOST"] && !ENV["BINDING"]
223
225
  ActiveSupport::Deprecation.warn(<<-MSG.squish)
224
- Using the `HOST` environment to specify the IP is deprecated and will be removed in Rails 6.1.
225
- Please use `BINDING` environment instead.
226
+ Using the `HOST` environment variable to specify the IP is deprecated and will be removed in Rails 6.1.
227
+ Please use `BINDING` environment variable instead.
226
228
  MSG
227
229
 
228
230
  return ENV["HOST"]
@@ -255,7 +257,7 @@ module Rails
255
257
  end
256
258
 
257
259
  def self.banner(*)
258
- "rails server [thin/puma/webrick] [options]"
260
+ "rails server -u [thin/puma/webrick] [options]"
259
261
  end
260
262
 
261
263
  def prepare_restart
@@ -264,7 +266,7 @@ module Rails
264
266
 
265
267
  def deprecate_positional_rack_server_and_rewrite_to_option(original_options)
266
268
  if using
267
- ActiveSupport::Deprecation.warn(<<~MSG)
269
+ ActiveSupport::Deprecation.warn(<<~MSG.squish)
268
270
  Passing the Rack server name as a regular argument is deprecated
269
271
  and will be removed in the next Rails version. Please, use the -u
270
272
  option instead.
@@ -230,7 +230,7 @@ module Rails
230
230
  #
231
231
  # If +MyEngine+ is isolated, The routes above will point to
232
232
  # <tt>MyEngine::ArticlesController</tt>. You also don't need to use longer
233
- # url helpers like +my_engine_articles_path+. Instead, you should simply use
233
+ # URL helpers like +my_engine_articles_path+. Instead, you should simply use
234
234
  # +articles_path+, like you would do with your main application.
235
235
  #
236
236
  # To make this behavior consistent with other parts of the framework,
@@ -238,7 +238,7 @@ module Rails
238
238
  # normal Rails app, when you use a namespaced model such as
239
239
  # <tt>Namespace::Article</tt>, <tt>ActiveModel::Naming</tt> will generate
240
240
  # names with the prefix "namespace". In an isolated engine, the prefix will
241
- # be omitted in url helpers and form fields, for convenience.
241
+ # be omitted in URL helpers and form fields, for convenience.
242
242
  #
243
243
  # polymorphic_url(MyEngine::Article.new)
244
244
  # # => "articles_path" # not "my_engine_articles_path"
@@ -286,11 +286,11 @@ module Rails
286
286
  # Note that the <tt>:as</tt> option given to mount takes the <tt>engine_name</tt> as default, so most of the time
287
287
  # you can simply omit it.
288
288
  #
289
- # Finally, if you want to generate a url to an engine's route using
289
+ # Finally, if you want to generate a URL to an engine's route using
290
290
  # <tt>polymorphic_url</tt>, you also need to pass the engine helper. Let's
291
291
  # say that you want to create a form pointing to one of the engine's routes.
292
292
  # All you need to do is pass the helper as the first element in array with
293
- # attributes for url:
293
+ # attributes for URL:
294
294
  #
295
295
  # form_for([my_engine, @user])
296
296
  #
@@ -469,13 +469,16 @@ module Rails
469
469
  self
470
470
  end
471
471
 
472
- # Eager load the application by loading all ruby
473
- # files inside eager_load paths.
474
472
  def eager_load!
475
- if Rails.autoloaders.zeitwerk_enabled?
476
- eager_load_with_zeitwerk!
477
- else
478
- eager_load_with_dependencies!
473
+ # Already done by Zeitwerk::Loader.eager_load_all in the finisher.
474
+ return if Rails.autoloaders.zeitwerk_enabled?
475
+
476
+ config.eager_load_paths.each do |load_path|
477
+ # Starts after load_path plus a slash, ends before ".rb".
478
+ relname_range = (load_path.to_s.length + 1)...-3
479
+ Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
480
+ require_dependency file[relname_range]
481
+ end
479
482
  end
480
483
  end
481
484
 
@@ -530,9 +533,9 @@ module Rails
530
533
 
531
534
  # Defines the routes for this engine. If a block is given to
532
535
  # routes, it is appended to the engine.
533
- def routes
536
+ def routes(&block)
534
537
  @routes ||= ActionDispatch::Routing::RouteSet.new_with_config(config)
535
- @routes.append(&Proc.new) if block_given?
538
+ @routes.append(&block) if block_given?
536
539
  @routes
537
540
  end
538
541
 
@@ -547,7 +550,13 @@ module Rails
547
550
  # Blog::Engine.load_seed
548
551
  def load_seed
549
552
  seed_file = paths["db/seeds.rb"].existent.first
550
- with_inline_jobs { load(seed_file) } if seed_file
553
+ return unless seed_file
554
+
555
+ if config.try(:active_job)&.queue_adapter == :async
556
+ with_inline_jobs { load(seed_file) }
557
+ else
558
+ load(seed_file)
559
+ end
551
560
  end
552
561
 
553
562
  # Add configured load paths to Ruby's load path, and remove duplicate entries.
@@ -567,12 +576,15 @@ module Rails
567
576
  ActiveSupport::Dependencies.autoload_paths.unshift(*_all_autoload_paths)
568
577
  ActiveSupport::Dependencies.autoload_once_paths.unshift(*_all_autoload_once_paths)
569
578
 
570
- # Freeze so future modifications will fail rather than do nothing mysteriously
571
579
  config.autoload_paths.freeze
572
- config.eager_load_paths.freeze
573
580
  config.autoload_once_paths.freeze
574
581
  end
575
582
 
583
+ initializer :set_eager_load_paths, before: :bootstrap_hook do
584
+ ActiveSupport::Dependencies._eager_load_paths.merge(config.eager_load_paths)
585
+ config.eager_load_paths.freeze
586
+ end
587
+
576
588
  initializer :add_routing_paths do |app|
577
589
  routing_paths = paths["config/routes.rb"].existent
578
590
 
@@ -651,22 +663,6 @@ module Rails
651
663
 
652
664
  private
653
665
 
654
- def eager_load_with_zeitwerk!
655
- (config.eager_load_paths - Zeitwerk::Loader.all_dirs).each do |path|
656
- Dir.glob("#{path}/**/*.rb").sort.each { |file| require file }
657
- end
658
- end
659
-
660
- def eager_load_with_dependencies!
661
- config.eager_load_paths.each do |load_path|
662
- # Starts after load_path plus a slash, ends before ".rb".
663
- relname_range = (load_path.to_s.length + 1)...-3
664
- Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
665
- require_dependency file[relname_range]
666
- end
667
- end
668
- end
669
-
670
666
  def load_config_initializer(initializer) # :doc:
671
667
  ActiveSupport::Notifications.instrument("load_config_initializer.railties", initializer: initializer) do
672
668
  load(initializer)
@@ -10,7 +10,7 @@ module Rails
10
10
  MAJOR = 6
11
11
  MINOR = 0
12
12
  TINY = 0
13
- PRE = "beta3"
13
+ PRE = "rc1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -35,6 +35,8 @@ module Rails
35
35
  rails: {
36
36
  actions: "-a",
37
37
  orm: "-o",
38
+ javascripts: "-j",
39
+ javascript_engine: "-je",
38
40
  resource_controller: "-c",
39
41
  scaffold_controller: "-c",
40
42
  stylesheets: "-y",
@@ -307,7 +307,7 @@ module Rails
307
307
  def assets_gemfile_entry
308
308
  return [] if options[:skip_sprockets]
309
309
 
310
- GemfileEntry.version("sass-rails", "~> 5.0", "Use SCSS for stylesheets")
310
+ GemfileEntry.version("sass-rails", "~> 5", "Use SCSS for stylesheets")
311
311
  end
312
312
 
313
313
  def webpacker_gemfile_entry
@@ -316,7 +316,7 @@ module Rails
316
316
  if options.dev? || options.edge?
317
317
  GemfileEntry.github "webpacker", "rails/webpacker", nil, "Use development version of Webpacker"
318
318
  else
319
- GemfileEntry.version "webpacker", ">= 4.0.0.rc.3", "Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker"
319
+ GemfileEntry.version "webpacker", "~> 4.0", "Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker"
320
320
  end
321
321
  end
322
322
 
@@ -7,11 +7,11 @@ module Rails
7
7
 
8
8
  private
9
9
  def app_name
10
- @app_name ||= original_app_name.tr("-", "_")
10
+ @app_name ||= original_app_name.tr('\\', "").tr("-. ", "_")
11
11
  end
12
12
 
13
13
  def original_app_name
14
- @original_app_name ||= (defined_app_const_base? ? defined_app_name : File.basename(destination_root)).tr('\\', "").tr(". ", "_")
14
+ @original_app_name ||= defined_app_const_base? ? defined_app_name : File.basename(destination_root)
15
15
  end
16
16
 
17
17
  def defined_app_name
@@ -15,7 +15,7 @@ module Rails
15
15
  case database
16
16
  when "mysql" then ["mysql2", [">= 0.4.4"]]
17
17
  when "postgresql" then ["pg", [">= 0.18", "< 2.0"]]
18
- when "sqlite3" then ["sqlite3", ["~> 1.3", ">= 1.3.6"]]
18
+ when "sqlite3" then ["sqlite3", ["~> 1.4"]]
19
19
  when "oracle" then ["activerecord-oracle_enhanced-adapter", nil]
20
20
  when "frontbase" then ["ruby-frontbase", nil]
21
21
  when "sqlserver" then ["activerecord-sqlserver-adapter", nil]
@@ -4,9 +4,9 @@
4
4
  <h2><%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
5
5
 
6
6
  <ul>
7
- <%% <%= singular_table_name %>.errors.full_messages.each do |message| %>
8
- <li><%%= message %></li>
9
- <%% end %>
7
+ <%% <%= singular_table_name %>.errors.full_messages.each do |message| %>
8
+ <li><%%= message %></li>
9
+ <%% end %>
10
10
  </ul>
11
11
  </div>
12
12
  <%% end %>
@@ -21,6 +21,9 @@
21
21
  <div class="field">
22
22
  <%%= form.label :password_confirmation %>
23
23
  <%%= form.password_field :password_confirmation %>
24
+ <% elsif attribute.attachments? -%>
25
+ <%%= form.label :<%= attribute.column_name %> %>
26
+ <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, multiple: true %>
24
27
  <% else -%>
25
28
  <%%= form.label :<%= attribute.column_name %> %>
26
29
  <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %> %>
@@ -3,7 +3,15 @@
3
3
  <% attributes.reject(&:password_digest?).each do |attribute| -%>
4
4
  <p>
5
5
  <strong><%= attribute.human_name %>:</strong>
6
+ <% if attribute.attachment? -%>
7
+ <%%= link_to @<%= singular_table_name %>.<%= attribute.column_name %>.filename, @<%= singular_table_name %>.<%= attribute.column_name %> %>
8
+ <% elsif attribute.attachments? -%>
9
+ <%% @<%= singular_table_name %>.<%= attribute.column_name %>.each do |<%= attribute.singular_name %>| %>
10
+ <div><%%= link_to <%= attribute.singular_name %>.filename, <%= attribute.singular_name %> %></div>
11
+ <%% end %>
12
+ <% else -%>
6
13
  <%%= @<%= singular_table_name %>.<%= attribute.column_name %> %>
14
+ <% end -%>
7
15
  </p>
8
16
 
9
17
  <% end -%>