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