Class: RubyUiScaffold::Generators::ScaffoldGenerator

Inherits:
Rails::Generators::NamedBase
  • Object
show all
Includes:
Rails::Generators::ResourceHelpers, AttributeHelpers, ComponentInstaller
Defined in:
lib/generators/ruby_ui_scaffold/scaffold/scaffold_generator.rb

Overview

The "template engine" — generates the Phlex view classes for index, show, new, edit, and a shared form under the Views:: namespace (matches the convention installed by phlex:install, which creates Views::Base and wires the app/views/ autoloader).

Invoked indirectly via ruby_ui_scaffold:scaffold_controller, which sets template_engine default to ruby_ui_scaffold.

Constant Summary

Constants included from AttributeHelpers

AttributeHelpers::EXCLUDED_FROM_SORT

Instance Method Summary collapse

Methods included from ComponentInstaller

#component_installed?, #uninstalled_components

Methods included from AttributeHelpers

#reference_associations, #searchable_columns, #sortable_columns

Instance Method Details

#create_view_filesObject



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/generators/ruby_ui_scaffold/scaffold/scaffold_generator.rb', line 53

def create_view_files
  empty_directory File.join("app/views", controller_file_path)

  # Index has two flavors: plain Table (default) or DataTable (--datatable).
  # Both compile down to `app/views/<resource>/index.rb`.
  index_template = options[:datatable] ? "index_data_table.rb.tt" : "index.rb.tt"
  template index_template, File.join("app/views", controller_file_path, "index.rb")

  %w[show new edit form].each do |view|
    template "#{view}.rb.tt", File.join("app/views", controller_file_path, "#{view}.rb")
  end
end

#inject_scaffold_helpers_into_components_baseObject

Inject the Phlex helpers the scaffold-generated views rely on into Components::Base. phlex:install / ruby_ui:install create the file but only include Phlex::Rails::Helpers::Routes + RubyUI — the scaffold also needs form_with, link_to, button_to, request (for the form's "Back" link), and lucide_icon. When --literal is passed, also extend Literal::Properties so the generated views' prop macros resolve. Each line is added only if missing, so re-running is safe.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/generators/ruby_ui_scaffold/scaffold/scaffold_generator.rb', line 74

def inject_scaffold_helpers_into_components_base
  return if behavior == :revoke

  components_base = File.join(destination_root, "app/components/base.rb")
  return unless File.exist?(components_base)

  contents = File.read(components_base)

  helpers = []
  helpers << "  extend Literal::Properties" if options[:literal] && !contents.include?("Literal::Properties")
  helpers << "  include Phlex::Rails::Helpers::FormWith" unless contents.include?("Phlex::Rails::Helpers::FormWith")
  helpers << "  include Phlex::Rails::Helpers::LinkTo" unless contents.include?("Phlex::Rails::Helpers::LinkTo")
  helpers << "  include Phlex::Rails::Helpers::ButtonTo" unless contents.include?("Phlex::Rails::Helpers::ButtonTo")
  helpers << "  include Phlex::Rails::Helpers::Request" unless contents.include?("Phlex::Rails::Helpers::Request")
  helpers << "  register_output_helper :lucide_icon" unless contents.include?("register_output_helper :lucide_icon")

  return if helpers.empty?

  inject_into_file components_base, after: /class Components::Base.*\n/ do
    helpers.join("\n") + "\n"
  end
end

#install_required_componentsObject

Install the ruby_ui components THIS scaffold references, on demand, after the views are written. The BASE set is already installed by ruby_ui_scaffold:install; here we add the column/flag-specific ones (badge, checkbox, textarea, combobox, select, date_picker, data_table) — but request the full set and skip whatever's already present, so it works whether or not :install ran first. Non-blocking: a component that fails to install just warns (the view files already exist). Gated like the auto-install: skipped on --skip-install or when there's no app bin/rails to drive ruby_ui:component (e.g. the test harness).



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/generators/ruby_ui_scaffold/scaffold/scaffold_generator.rb', line 106

def install_required_components
  return if behavior == :revoke
  return if options[:skip_install] || !app_bin_rails?

  needed = ::RubyUiScaffold::ComponentResolver.call(
    attributes: attributes, datatable: options[:datatable]
  )
  missing = uninstalled_components(needed)
  return if missing.empty?

  say "\n  → Installing #{missing.size} ruby_ui component(s) this scaffold uses", :cyan
  missing.each do |component|
    say "      • #{component}", :cyan
    install_ruby_ui_component(component)
  end
end

#preflight_checksObject

Generator action — runs before view files are written. The generated views need phlex (Views::Base) and ruby_ui (RubyUI mixed into Components::Base); without them, requests 500 at runtime. When either is missing we auto-run the idempotent ruby_ui_scaffold:install so the scaffold works out of the box. Falls back to a non-blocking warning when auto-install isn't possible (no app bin/rails) or is opted out with --skip-install.



47
48
49
50
51
# File 'lib/generators/ruby_ui_scaffold/scaffold/scaffold_generator.rb', line 47

def preflight_checks
  return if behavior == :revoke

  ensure_phlex_and_ruby_ui_installed
end