railties 7.1.5.1 → 7.2.2.1

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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +197 -767
  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 +68 -33
  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 +22 -89
  11. data/lib/rails/backtrace_cleaner.rb +14 -1
  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 +102 -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 +146 -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 +7 -7
  30. data/lib/rails/gem_version.rb +2 -2
  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/rails/app/app_generator.rb +56 -28
  39. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +22 -15
  40. data/lib/rails/generators/rails/app/templates/Gemfile.tt +17 -17
  41. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
  42. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
  43. data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
  44. data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
  45. data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
  46. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
  47. data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
  48. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
  49. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  50. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +7 -0
  51. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
  52. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
  53. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +14 -7
  54. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +8 -0
  55. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +8 -5
  56. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -1
  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 +25 -35
  60. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +6 -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 +40 -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/rails/plugin/templates/test/test_helper.rb.tt +2 -2
  88. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +6 -4
  89. data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
  90. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +15 -1
  91. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
  92. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
  93. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
  94. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
  95. data/lib/rails/generators/testing/assertions.rb +20 -0
  96. data/lib/rails/generators/testing/behavior.rb +7 -6
  97. data/lib/rails/generators.rb +6 -2
  98. data/lib/rails/health_controller.rb +1 -1
  99. data/lib/rails/info.rb +2 -2
  100. data/lib/rails/mailers_controller.rb +14 -1
  101. data/lib/rails/paths.rb +2 -2
  102. data/lib/rails/pwa_controller.rb +15 -0
  103. data/lib/rails/rack/logger.rb +15 -7
  104. data/lib/rails/railtie/configurable.rb +2 -2
  105. data/lib/rails/railtie.rb +2 -3
  106. data/lib/rails/tasks/framework.rake +0 -26
  107. data/lib/rails/tasks/tmp.rake +1 -1
  108. data/lib/rails/templates/layouts/application.html.erb +1 -1
  109. data/lib/rails/templates/rails/mailers/email.html.erb +12 -8
  110. data/lib/rails/templates/rails/welcome/index.html.erb +4 -2
  111. data/lib/rails/test_help.rb +2 -4
  112. data/lib/rails/test_unit/reporter.rb +8 -2
  113. data/lib/rails/test_unit/runner.rb +26 -2
  114. data/lib/rails/test_unit/test_parser.rb +45 -0
  115. data/lib/rails.rb +6 -3
  116. metadata +40 -30
  117. data/lib/rails/app_updater.rb +0 -52
  118. data/lib/rails/commands/secrets/USAGE +0 -61
  119. data/lib/rails/commands/secrets/secrets_command.rb +0 -47
  120. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
  121. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
  122. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
  123. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
  124. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
  125. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
  126. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -280
  127. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
  128. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
  129. data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
  130. data/lib/rails/ruby_version_check.rb +0 -17
  131. 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
+ "sqlite3"
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