railties 7.1.3.4 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +177 -742
  3. data/lib/minitest/rails_plugin.rb +5 -2
  4. data/lib/rails/all.rb +1 -3
  5. data/lib/rails/api/task.rb +6 -4
  6. data/lib/rails/application/bootstrap.rb +5 -6
  7. data/lib/rails/application/configuration.rb +73 -38
  8. data/lib/rails/application/dummy_config.rb +2 -2
  9. data/lib/rails/application/finisher.rb +7 -0
  10. data/lib/rails/application.rb +15 -86
  11. data/lib/rails/backtrace_cleaner.rb +18 -3
  12. data/lib/rails/cli.rb +0 -1
  13. data/lib/rails/command.rb +1 -1
  14. data/lib/rails/commands/app/update_command.rb +93 -0
  15. data/lib/rails/commands/boot/boot_command.rb +14 -0
  16. data/lib/rails/commands/console/console_command.rb +2 -21
  17. data/lib/rails/commands/console/irb_console.rb +137 -0
  18. data/lib/rails/commands/credentials/credentials_command.rb +2 -2
  19. data/lib/rails/commands/dbconsole/dbconsole_command.rb +21 -30
  20. data/lib/rails/commands/devcontainer/devcontainer_command.rb +39 -0
  21. data/lib/rails/commands/rake/rake_command.rb +1 -1
  22. data/lib/rails/commands/runner/runner_command.rb +14 -3
  23. data/lib/rails/commands/server/server_command.rb +5 -3
  24. data/lib/rails/commands/test/test_command.rb +2 -0
  25. data/lib/rails/configuration.rb +10 -1
  26. data/lib/rails/console/app.rb +5 -32
  27. data/lib/rails/console/helpers.rb +5 -16
  28. data/lib/rails/console/methods.rb +23 -0
  29. data/lib/rails/engine.rb +5 -5
  30. data/lib/rails/gem_version.rb +3 -3
  31. data/lib/rails/generators/app_base.rb +70 -49
  32. data/lib/rails/generators/base.rb +5 -1
  33. data/lib/rails/generators/database.rb +227 -69
  34. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +2 -0
  35. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +2 -0
  36. data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +2 -0
  37. data/lib/rails/generators/generated_attribute.rb +26 -1
  38. data/lib/rails/generators/migration.rb +3 -3
  39. data/lib/rails/generators/rails/app/app_generator.rb +53 -24
  40. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +22 -15
  41. data/lib/rails/generators/rails/app/templates/Gemfile.tt +16 -16
  42. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
  43. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
  44. data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
  45. data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
  46. data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
  47. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
  48. data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
  49. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
  50. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  51. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +7 -0
  52. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
  53. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
  54. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +14 -7
  55. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +5 -0
  56. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +8 -5
  57. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
  58. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +70 -0
  59. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +24 -26
  60. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +4 -0
  61. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +5 -0
  62. data/lib/rails/generators/rails/app/templates/dockerignore.tt +13 -0
  63. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +138 -0
  64. data/lib/rails/generators/rails/app/templates/github/dependabot.yml +12 -0
  65. data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -3
  66. data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +66 -0
  67. data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
  68. data/lib/rails/generators/rails/app/templates/public/icon.svg +3 -0
  69. data/lib/rails/generators/rails/app/templates/rubocop.yml.tt +8 -0
  70. data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt +1 -1
  71. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
  72. data/lib/rails/generators/rails/db/system/change/change_generator.rb +131 -20
  73. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +166 -0
  74. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +3 -0
  75. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +47 -0
  76. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +37 -0
  77. data/lib/rails/generators/rails/migration/migration_generator.rb +4 -0
  78. data/lib/rails/generators/rails/plugin/plugin_generator.rb +38 -7
  79. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
  80. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +5 -1
  81. data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +2 -0
  82. data/lib/rails/generators/rails/plugin/templates/bin/rubocop.tt +7 -0
  83. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +103 -0
  84. data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +12 -0
  85. data/lib/rails/generators/rails/plugin/templates/rubocop.yml.tt +8 -0
  86. data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt +1 -1
  87. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +6 -4
  88. data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
  89. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +15 -1
  90. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
  91. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
  92. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
  93. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
  94. data/lib/rails/generators/testing/assertions.rb +20 -0
  95. data/lib/rails/generators/testing/behavior.rb +7 -6
  96. data/lib/rails/generators.rb +1 -1
  97. data/lib/rails/health_controller.rb +1 -1
  98. data/lib/rails/info.rb +2 -2
  99. data/lib/rails/mailers_controller.rb +14 -1
  100. data/lib/rails/paths.rb +2 -2
  101. data/lib/rails/pwa_controller.rb +15 -0
  102. data/lib/rails/rack/logger.rb +15 -7
  103. data/lib/rails/railtie/configurable.rb +2 -2
  104. data/lib/rails/railtie.rb +2 -3
  105. data/lib/rails/tasks/framework.rake +0 -26
  106. data/lib/rails/tasks/tmp.rake +1 -1
  107. data/lib/rails/templates/layouts/application.html.erb +1 -1
  108. data/lib/rails/templates/rails/mailers/email.html.erb +12 -8
  109. data/lib/rails/templates/rails/welcome/index.html.erb +4 -2
  110. data/lib/rails/test_help.rb +2 -4
  111. data/lib/rails/test_unit/reporter.rb +8 -2
  112. data/lib/rails/test_unit/runner.rb +26 -2
  113. data/lib/rails/test_unit/test_parser.rb +45 -0
  114. data/lib/rails.rb +7 -4
  115. metadata +42 -32
  116. data/lib/rails/app_updater.rb +0 -40
  117. data/lib/rails/commands/secrets/USAGE +0 -61
  118. data/lib/rails/commands/secrets/secrets_command.rb +0 -47
  119. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
  120. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
  121. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
  122. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
  123. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
  124. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
  125. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -284
  126. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
  127. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
  128. data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
  129. data/lib/rails/ruby_version_check.rb +0 -17
  130. data/lib/rails/secrets.rb +0 -110
@@ -12,12 +12,15 @@ require "active_support/core_ext/array/extract_options"
12
12
  module Rails
13
13
  module Generators
14
14
  class AppBase < Base # :nodoc:
15
- include Database
16
15
  include AppName
17
16
 
18
- NODE_LTS_VERSION = "18.15.0"
17
+ NODE_LTS_VERSION = "20.11.1"
19
18
  BUN_VERSION = "1.0.1"
20
19
 
20
+ JAVASCRIPT_OPTIONS = %w( importmap bun webpack esbuild rollup )
21
+ CSS_OPTIONS = %w( tailwind bootstrap bulma postcss sass )
22
+ ASSET_PIPELINE_OPTIONS = %w( none sprockets propshaft )
23
+
21
24
  attr_accessor :rails_template
22
25
  add_shebang_option!
23
26
 
@@ -35,7 +38,8 @@ module Rails
35
38
  desc: "Path to some #{name} template (can be a filesystem path or URL)"
36
39
 
37
40
  class_option :database, type: :string, aliases: "-d", default: "sqlite3",
38
- desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"
41
+ enum: Database::DATABASES,
42
+ desc: "Preconfigure for selected database"
39
43
 
40
44
  class_option :skip_git, type: :boolean, aliases: "-G", default: nil,
41
45
  desc: "Skip git init, .gitignore and .gitattributes"
@@ -71,7 +75,8 @@ module Rails
71
75
  class_option :skip_asset_pipeline, type: :boolean, aliases: "-A", default: nil
72
76
 
73
77
  class_option :asset_pipeline, type: :string, aliases: "-a", default: "sprockets",
74
- desc: "Choose your asset pipeline [options: sprockets (default), propshaft]"
78
+ enum: ASSET_PIPELINE_OPTIONS,
79
+ desc: "Choose your asset pipeline"
75
80
 
76
81
  class_option :skip_javascript, type: :boolean, aliases: ["-J", "--skip-js"], default: (true if name == "plugin"),
77
82
  desc: "Skip JavaScript files"
@@ -94,9 +99,21 @@ module Rails
94
99
  class_option :skip_dev_gems, type: :boolean, default: nil,
95
100
  desc: "Skip development gems (e.g., web-console)"
96
101
 
102
+ class_option :skip_rubocop, type: :boolean, default: nil,
103
+ desc: "Skip RuboCop setup"
104
+
105
+ class_option :skip_brakeman, type: :boolean, default: nil,
106
+ desc: "Skip brakeman setup"
107
+
108
+ class_option :skip_ci, type: :boolean, default: nil,
109
+ desc: "Skip GitHub CI files"
110
+
97
111
  class_option :dev, type: :boolean, default: nil,
98
112
  desc: "Set up the #{name} with Gemfile pointing to your Rails checkout"
99
113
 
114
+ class_option :devcontainer, type: :boolean, default: false,
115
+ desc: "Generate devcontainer files"
116
+
100
117
  class_option :edge, type: :boolean, default: nil,
101
118
  desc: "Set up the #{name} with a Gemfile pointing to the #{edge_branch} branch on the Rails repository"
102
119
 
@@ -260,7 +277,7 @@ module Rails
260
277
  def database_gemfile_entry # :doc:
261
278
  return if options[:skip_active_record]
262
279
 
263
- gem_name, gem_version = gem_for_database
280
+ gem_name, gem_version = database.gem
264
281
  GemfileEntry.version gem_name, gem_version,
265
282
  "Use #{options[:database]} as the database for Active Record"
266
283
  end
@@ -345,6 +362,10 @@ module Rails
345
362
  options[:skip_active_storage]
346
363
  end
347
364
 
365
+ def skip_storage? # :doc:
366
+ skip_active_storage? && !sqlite3?
367
+ end
368
+
348
369
  def skip_action_cable? # :doc:
349
370
  options[:skip_action_cable]
350
371
  end
@@ -373,6 +394,25 @@ module Rails
373
394
  skip_asset_pipeline? || options[:asset_pipeline] != "propshaft"
374
395
  end
375
396
 
397
+ def skip_rubocop?
398
+ options[:skip_rubocop]
399
+ end
400
+
401
+ def skip_brakeman?
402
+ options[:skip_brakeman]
403
+ end
404
+
405
+ def skip_ci?
406
+ options[:skip_ci]
407
+ end
408
+
409
+ def skip_devcontainer?
410
+ !options[:devcontainer]
411
+ end
412
+
413
+ def devcontainer?
414
+ options[:devcontainer]
415
+ end
376
416
 
377
417
  class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
378
418
  def initialize(name, version, comment, options = {}, commented_out = false)
@@ -410,10 +450,6 @@ module Rails
410
450
  end
411
451
  end
412
452
 
413
- def gem_ruby_version
414
- Gem::Version.new(Gem::VERSION) >= Gem::Version.new("3.3.13") ? Gem.ruby_version : RUBY_VERSION
415
- end
416
-
417
453
  def rails_prerelease?
418
454
  options.dev? || options.edge? || options.main?
419
455
  end
@@ -535,17 +571,28 @@ module Rails
535
571
  binfixups
536
572
  end
537
573
 
538
- def dockerfile_build_packages
539
- # start with the essentials
540
- packages = %w(build-essential git pkg-config)
574
+ def dockerfile_base_packages
575
+ # Add curl to work with the default healthcheck strategy in Kamal
576
+ packages = ["curl"]
541
577
 
542
- # add database support
543
- packages << build_package_for_database unless skip_active_record?
578
+ # ActiveRecord databases
579
+ packages << database.base_package unless skip_active_record?
544
580
 
545
581
  # ActiveStorage preview support
546
582
  packages << "libvips" unless skip_active_storage?
547
583
 
548
- packages << "curl" if using_js_runtime?
584
+ # jemalloc for memory optimization
585
+ packages << "libjemalloc2"
586
+
587
+ packages.compact.sort
588
+ end
589
+
590
+ def dockerfile_build_packages
591
+ # start with the essentials
592
+ packages = %w(build-essential git pkg-config)
593
+
594
+ # add database support
595
+ packages << database.build_package unless skip_active_record?
549
596
 
550
597
  packages << "unzip" if using_bun?
551
598
 
@@ -553,43 +600,14 @@ module Rails
553
600
  if using_node?
554
601
  packages << "node-gyp" # pkg-config already listed above
555
602
 
556
- # module build process depends on Python, and debian changed
557
- # how python is installed with the bullseye release. Below
558
- # is based on debian release included with the Ruby images on
559
- # Dockerhub.
560
- case Gem.ruby_version.to_s
561
- when /^2\.7/
562
- bullseye = Gem.ruby_version >= Gem::Version.new("2.7.4")
563
- when /^3\.0/
564
- bullseye = Gem.ruby_version >= Gem::Version.new("3.0.2")
565
- else
566
- bullseye = true
567
- end
568
-
569
- if bullseye
570
- packages << "python-is-python3"
571
- else
572
- packages << "python"
573
- end
603
+ packages << "python-is-python3"
574
604
  end
575
605
 
576
606
  packages.compact.sort
577
607
  end
578
608
 
579
- def dockerfile_deploy_packages
580
- # Add curl to work with the default healthcheck strategy in Kamal
581
- packages = ["curl"]
582
-
583
- # ActiveRecord databases
584
- packages << deploy_package_for_database unless skip_active_record?
585
-
586
- # ActiveStorage preview support
587
- packages << "libvips" unless skip_active_storage?
588
-
589
- packages.compact.sort
590
- end
591
-
592
609
  def css_gemfile_entry
610
+ return if options[:api]
593
611
  return unless options[:css]
594
612
 
595
613
  if !using_js_runtime? && options[:css] == "tailwind"
@@ -656,7 +674,6 @@ module Rails
656
674
  if !File.exist?(File.expand_path("Gemfile", destination_root))
657
675
  create_file("Gemfile", <<~GEMFILE)
658
676
  source "https://rubygems.org"
659
- git_source(:github) { |repo| "https://github.com/\#{repo}.git" }
660
677
  #{rails_gemfile_entry}
661
678
  GEMFILE
662
679
 
@@ -674,7 +691,7 @@ module Rails
674
691
  end
675
692
 
676
693
  def run_bundle
677
- bundle_command("install", "BUNDLE_IGNORE_MESSAGES" => "1") if bundle_install?
694
+ bundle_command("install --quiet", "BUNDLE_IGNORE_MESSAGES" => "1") if bundle_install?
678
695
  end
679
696
 
680
697
  def run_javascript
@@ -752,11 +769,15 @@ module Rails
752
769
  def dockerfile_chown_directories
753
770
  directories = %w(log tmp)
754
771
 
755
- directories << "storage" unless skip_active_storage? && !sqlite3?
772
+ directories << "storage" unless skip_storage?
756
773
  directories << "db" unless skip_active_record?
757
774
 
758
775
  directories.sort
759
776
  end
777
+
778
+ def database
779
+ @database ||= Database.build(options[:database])
780
+ end
760
781
  end
761
782
  end
762
783
  end
@@ -222,7 +222,7 @@ module Rails
222
222
  end
223
223
 
224
224
  # Returns the default source root for a given generator. This is used internally
225
- # by \Rails to set its generators source root. If you want to customize your source
225
+ # by Rails to set its generators source root. If you want to customize your source
226
226
  # root, you should use source_root.
227
227
  def self.default_source_root
228
228
  return unless base_name && generator_name
@@ -423,6 +423,10 @@ module Rails
423
423
  path = File.expand_path(File.join(base_name, generator_name), base_root)
424
424
  path if File.exist?(path)
425
425
  end
426
+
427
+ def gem_ruby_version
428
+ Gem::Version.new(Gem::VERSION) >= Gem::Version.new("3.3.13") ? Gem.ruby_version : RUBY_VERSION
429
+ end
426
430
  end
427
431
  end
428
432
  end
@@ -2,83 +2,76 @@
2
2
 
3
3
  module Rails
4
4
  module Generators
5
- module Database # :nodoc:
6
- JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc )
7
- DATABASES = %w( mysql trilogy postgresql sqlite3 oracle sqlserver ) + JDBC_DATABASES
8
-
9
- def initialize(*)
10
- super
11
- convert_database_option_for_jruby
12
- end
13
-
14
- def gem_for_database(database = options[:database])
15
- case database
16
- when "mysql" then ["mysql2", ["~> 0.5"]]
17
- when "trilogy" then ["trilogy", ["~> 2.4"]]
18
- when "postgresql" then ["pg", ["~> 1.1"]]
19
- when "sqlite3" then ["sqlite3", ["~> 1.4"]]
20
- when "oracle" then ["activerecord-oracle_enhanced-adapter", nil]
21
- when "sqlserver" then ["activerecord-sqlserver-adapter", nil]
22
- when "jdbcmysql" then ["activerecord-jdbcmysql-adapter", nil]
23
- when "jdbcsqlite3" then ["activerecord-jdbcsqlite3-adapter", nil]
24
- when "jdbcpostgresql" then ["activerecord-jdbcpostgresql-adapter", nil]
25
- when "jdbc" then ["activerecord-jdbc-adapter", nil]
26
- else [database, nil]
27
- end
28
- end
29
-
30
- def docker_for_database_build(database = options[:database])
31
- case database
32
- when "mysql" then "build-essential default-libmysqlclient-dev git"
33
- when "trilogy" then "build-essential default-libmysqlclient-dev git"
34
- when "postgresql" then "build-essential git libpq-dev"
35
- when "sqlite3" then "build-essential git"
36
- else nil
37
- end
38
- end
39
-
40
- def docker_for_database_deploy(database = options[:database])
41
- case database
42
- when "mysql" then "curl default-mysql-client libvips"
43
- when "trilogy" then "curl default-mysql-client libvips"
44
- when "postgresql" then "curl libvips postgresql-client"
45
- when "sqlite3" then "curl libsqlite3-0 libvips"
46
- else nil
47
- end
48
- end
49
-
50
- def convert_database_option_for_jruby
51
- if defined?(JRUBY_VERSION)
52
- opt = options.dup
53
- case opt[:database]
54
- when "postgresql" then opt[:database] = "jdbcpostgresql"
55
- when "mysql" then opt[:database] = "jdbcmysql"
56
- when "sqlite3" then opt[:database] = "jdbcsqlite3"
5
+ class Database
6
+ DATABASES = %w( mysql trilogy postgresql sqlite3 )
7
+
8
+ class << self
9
+ def build(database_name)
10
+ case database_name
11
+ when "mysql" then MySQL.new
12
+ when "postgresql" then PostgreSQL.new
13
+ when "trilogy" then MariaDB.new
14
+ when "sqlite3" then SQLite3.new
15
+ else Null.new
57
16
  end
58
- self.options = opt.freeze
59
17
  end
60
- end
61
18
 
62
- def build_package_for_database(database = options[:database])
63
- case database
64
- when "mysql" then "default-libmysqlclient-dev"
65
- when "postgresql" then "libpq-dev"
66
- else nil
19
+ def all
20
+ @all ||= [
21
+ MySQL.new,
22
+ PostgreSQL.new,
23
+ MariaDB.new,
24
+ SQLite3.new,
25
+ ]
67
26
  end
68
27
  end
69
28
 
70
- def deploy_package_for_database(database = options[:database])
71
- case database
72
- when "mysql" then "default-mysql-client"
73
- when "postgresql" then "postgresql-client"
74
- when "sqlite3" then "libsqlite3-0"
75
- else nil
76
- end
29
+ def name
30
+ raise NotImplementedError
31
+ end
32
+
33
+ def service
34
+ raise NotImplementedError
35
+ end
36
+
37
+ def port
38
+ raise NotImplementedError
39
+ end
40
+
41
+ def feature_name
42
+ raise NotImplementedError
77
43
  end
78
44
 
79
- private
80
- def mysql_socket
81
- @mysql_socket ||= [
45
+ def gem
46
+ raise NotImplementedError
47
+ end
48
+
49
+ def base_package
50
+ raise NotImplementedError
51
+ end
52
+
53
+ def build_package
54
+ raise NotImplementedError
55
+ end
56
+
57
+ def socket; end
58
+ def host; end
59
+
60
+ def feature
61
+ return unless feature_name
62
+
63
+ { feature_name => {} }
64
+ end
65
+
66
+ def volume
67
+ return unless service
68
+
69
+ "#{name}-data"
70
+ end
71
+
72
+ module MySqlSocket
73
+ def socket
74
+ @socket ||= [
82
75
  "/tmp/mysql.sock", # default
83
76
  "/var/run/mysqld/mysqld.sock", # debian/gentoo
84
77
  "/var/tmp/mysql.sock", # freebsd
@@ -90,6 +83,171 @@ module Rails
90
83
  "/opt/lampp/var/mysql/mysql.sock" # xampp for linux
91
84
  ].find { |f| File.exist?(f) } unless Gem.win_platform?
92
85
  end
86
+
87
+ def host
88
+ "localhost"
89
+ end
90
+ end
91
+
92
+ class MySQL < Database
93
+ include MySqlSocket
94
+
95
+ def name
96
+ "mysql"
97
+ end
98
+
99
+ def service
100
+ {
101
+ "image" => "mysql/mysql-server:8.0",
102
+ "restart" => "unless-stopped",
103
+ "environment" => {
104
+ "MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
105
+ "MYSQL_ROOT_HOST" => "%"
106
+ },
107
+ "volumes" => ["mysql-data:/var/lib/mysql"],
108
+ "networks" => ["default"],
109
+ }
110
+ end
111
+
112
+ def port
113
+ 3306
114
+ end
115
+
116
+ def gem
117
+ ["mysql2", ["~> 0.5"]]
118
+ end
119
+
120
+ def base_package
121
+ "default-mysql-client"
122
+ end
123
+
124
+ def build_package
125
+ "default-libmysqlclient-dev"
126
+ end
127
+
128
+ def feature_name
129
+ "ghcr.io/rails/devcontainer/features/mysql-client"
130
+ end
131
+ end
132
+
133
+ class PostgreSQL < Database
134
+ def name
135
+ "postgres"
136
+ end
137
+
138
+ def service
139
+ {
140
+ "image" => "postgres:16.1",
141
+ "restart" => "unless-stopped",
142
+ "networks" => ["default"],
143
+ "volumes" => ["postgres-data:/var/lib/postgresql/data"],
144
+ "environment" => {
145
+ "POSTGRES_USER" => "postgres",
146
+ "POSTGRES_PASSWORD" => "postgres"
147
+ }
148
+ }
149
+ end
150
+
151
+ def port
152
+ 5432
153
+ end
154
+
155
+ def gem
156
+ ["pg", ["~> 1.1"]]
157
+ end
158
+
159
+ def base_package
160
+ "postgresql-client"
161
+ end
162
+
163
+ def build_package
164
+ "libpq-dev"
165
+ end
166
+
167
+ def feature_name
168
+ "ghcr.io/rails/devcontainer/features/postgres-client"
169
+ end
170
+ end
171
+
172
+ class MariaDB < Database
173
+ include MySqlSocket
174
+
175
+ def name
176
+ "mariadb"
177
+ end
178
+
179
+ def service
180
+ {
181
+ "image" => "mariadb:10.5",
182
+ "restart" => "unless-stopped",
183
+ "networks" => ["default"],
184
+ "volumes" => ["mariadb-data:/var/lib/mysql"],
185
+ "environment" => {
186
+ "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
187
+ },
188
+ }
189
+ end
190
+
191
+ def port
192
+ 3306
193
+ end
194
+
195
+ def gem
196
+ ["trilogy", ["~> 2.7"]]
197
+ end
198
+
199
+ def base_package
200
+ nil
201
+ end
202
+
203
+ def build_package
204
+ nil
205
+ end
206
+
207
+ def feature_name
208
+ nil
209
+ end
210
+ end
211
+
212
+ class SQLite3 < Database
213
+ def name
214
+ "sqlite3"
215
+ end
216
+
217
+ def service
218
+ nil
219
+ end
220
+
221
+ def port
222
+ nil
223
+ end
224
+
225
+ def gem
226
+ ["sqlite3", [">= 1.4"]]
227
+ end
228
+
229
+ def base_package
230
+ "libsqlite3-0"
231
+ end
232
+
233
+ def build_package
234
+ nil
235
+ end
236
+
237
+ def feature_name
238
+ "ghcr.io/rails/devcontainer/features/sqlite3"
239
+ end
240
+ end
241
+
242
+ class Null < Database
243
+ def name; end
244
+ def service; end
245
+ def port; end
246
+ def volume; end
247
+ def base_package; end
248
+ def build_package; end
249
+ def feature_name; end
250
+ end
93
251
  end
94
252
  end
95
253
  end
@@ -1,3 +1,5 @@
1
+ <%% content_for :title, "Editing <%= human_name.downcase %>" %>
2
+
1
3
  <h1>Editing <%= human_name.downcase %></h1>
2
4
 
3
5
  <%%= render "form", <%= singular_table_name %>: @<%= singular_table_name %> %>
@@ -1,5 +1,7 @@
1
1
  <p style="color: green"><%%= notice %></p>
2
2
 
3
+ <%% content_for :title, "<%= human_name.pluralize %>" %>
4
+
3
5
  <h1><%= human_name.pluralize %></h1>
4
6
 
5
7
  <div id="<%= plural_table_name %>">
@@ -1,3 +1,5 @@
1
+ <%% content_for :title, "New <%= human_name.downcase %>" %>
2
+
1
3
  <h1>New <%= human_name.downcase %></h1>
2
4
 
3
5
  <%%= render "form", <%= singular_table_name %>: @<%= singular_table_name %> %>
@@ -72,7 +72,7 @@ module Rails
72
72
  def valid_type?(type)
73
73
  DEFAULT_TYPES.include?(type.to_s) ||
74
74
  !defined?(ActiveRecord::Base) ||
75
- ActiveRecord::Base.connection.valid_type?(type)
75
+ ActiveRecord::Base.lease_connection.valid_type?(type)
76
76
  end
77
77
 
78
78
  def valid_index_type?(index_type)
@@ -239,6 +239,31 @@ module Rails
239
239
  end
240
240
  end
241
241
  end
242
+
243
+ def to_s
244
+ if has_uniq_index?
245
+ "#{name}:#{type}#{print_attribute_options}:uniq"
246
+ elsif has_index?
247
+ "#{name}:#{type}#{print_attribute_options}:index"
248
+ else
249
+ "#{name}:#{type}#{print_attribute_options}"
250
+ end
251
+ end
252
+
253
+ private
254
+ def print_attribute_options
255
+ if attr_options.empty?
256
+ ""
257
+ elsif attr_options[:size]
258
+ "{#{attr_options[:size]}}"
259
+ elsif attr_options[:limit]
260
+ "{#{attr_options[:limit]}}"
261
+ elsif attr_options[:precision] && attr_options[:scale]
262
+ "{#{attr_options[:precision]},#{attr_options[:scale]}}"
263
+ else
264
+ "{#{attr_options.keys.join(",")}}"
265
+ end
266
+ end
242
267
  end
243
268
  end
244
269
  end
@@ -7,7 +7,7 @@ module Rails
7
7
  module Generators
8
8
  # Holds common methods for migrations. It assumes that migrations have the
9
9
  # [0-9]*_name format and can be used by other frameworks (like Sequel)
10
- # just by implementing the next migration version method.
10
+ # just by implementing the +next_migration_number+ method.
11
11
  module Migration
12
12
  extend ActiveSupport::Concern
13
13
  attr_reader :migration_number, :migration_file_name, :migration_class_name
@@ -46,10 +46,10 @@ module Rails
46
46
  end
47
47
 
48
48
  # Creates a migration template at the given destination. The difference
49
- # to the default template method is that the migration version is appended
49
+ # to the default template method is that the migration number is prepended
50
50
  # to the destination file name.
51
51
  #
52
- # The migration version, migration file name, migration class name are
52
+ # The migration number, migration file name, migration class name are
53
53
  # available as instance variables in the template to be rendered.
54
54
  #
55
55
  # migration_template "migration.rb", "db/migrate/add_foo_to_bar.rb"