railties 6.0.0.beta3 → 6.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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 -%>