Class: Ruflet::Rails::ResourceComponent
- Inherits:
-
Object
- Object
- Ruflet::Rails::ResourceComponent
- Includes:
- UI::SharedControlForwarders
- Defined in:
- lib/ruflet/rails/resource_component.rb
Overview
Base class for a Ruflet CRUD resource.
The generated subclass owns the explicit CRUD UI (render, show, the create/edit form) AND the database calls (record.update, record.destroy!, model_class.new) — so a developer can read and change anything. This base provides only reusable, non-DB helpers: model resolution, record loading, field inference (resource_fields/display_fields/display_value), navigation (render_index/render_show/refresh), dialog management, snackbars, and the date/time picker value helpers.
The same subclass renders on web and on mobile/desktop. It is mounted from config/routes.rb (the route path is declared there, never in the component):
mount Ruflet::Rails.web_app(view: "ProductComponent"), at: "/products"
web_app(view:) calls ‘.render(page)` on the class, which is why the class method below is the entrypoint. The model is inferred from the class name (ProductComponent -> Product); override `model_class` to customize.
Instance Attribute Summary collapse
-
#controller ⇒ Object
readonly
Returns the value of attribute controller.
-
#page ⇒ Object
readonly
Returns the value of attribute page.
Class Method Summary collapse
-
.model(value = nil) ⇒ Object
Declare or read the managed model: ‘model Product` or inferred from the component class name.
-
.render(page, *_args) ⇒ Object
Entrypoint used by web_app(view: “…”) on each new session.
- .singular_title ⇒ Object
-
.title(value = nil) ⇒ Object
Declare or read the plural resource title shown on the index screen.
Instance Method Summary collapse
-
#display_fields ⇒ Object
Columns rendered in the index table / list tiles.
-
#display_value(record, field) ⇒ Object
Formats a single field for display.
-
#initialize(page, controller: nil) ⇒ ResourceComponent
constructor
A new instance of ResourceComponent.
-
#model_class ⇒ Object
— Resource configuration (override in the generated subclass) ——–.
-
#primary_label(record) ⇒ Object
— Index labels ——————————————————-.
-
#records ⇒ Object
— Record loading & persistence ————————————–.
-
#refresh ⇒ Object
Re-render the index after a create/update/destroy.
- #render_index ⇒ Object
- #render_show(record) ⇒ Object
-
#resource_fields ⇒ Object
Fields rendered on the detail (show) screen.
- #resource_title ⇒ Object
- #secondary_label(record) ⇒ Object
- #show_record(record) ⇒ Object
- #singular_title ⇒ Object
Constructor Details
#initialize(page, controller: nil) ⇒ ResourceComponent
Returns a new instance of ResourceComponent.
72 73 74 75 |
# File 'lib/ruflet/rails/resource_component.rb', line 72 def initialize(page, controller: nil) @page = page @controller = controller end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, **kwargs, &block) ⇒ Object (private)
Methods not found on the component fall back to an optional controller, kept for apps that still pair a component with a separate host object.
360 361 362 363 364 |
# File 'lib/ruflet/rails/resource_component.rb', line 360 def method_missing(name, *args, **kwargs, &block) return controller.__send__(name, *args, **kwargs, &block) if controller&.respond_to?(name, true) super end |
Instance Attribute Details
#controller ⇒ Object (readonly)
Returns the value of attribute controller.
32 33 34 |
# File 'lib/ruflet/rails/resource_component.rb', line 32 def controller @controller end |
#page ⇒ Object (readonly)
Returns the value of attribute page.
32 33 34 |
# File 'lib/ruflet/rails/resource_component.rb', line 32 def page @page end |
Class Method Details
.model(value = nil) ⇒ Object
Declare or read the managed model: ‘model Product` or inferred from the component class name.
42 43 44 45 |
# File 'lib/ruflet/rails/resource_component.rb', line 42 def model(value = nil) @model_class = value if value @model_class || inferred_model_class end |
.render(page, *_args) ⇒ Object
Entrypoint used by web_app(view: “…”) on each new session.
36 37 38 |
# File 'lib/ruflet/rails/resource_component.rb', line 36 def render(page, *_args) new(page).render_index end |
.singular_title ⇒ Object
53 54 55 |
# File 'lib/ruflet/rails/resource_component.rb', line 53 def singular_title model_name ? model_name.human.titleize : "Record" end |
.title(value = nil) ⇒ Object
Declare or read the plural resource title shown on the index screen.
48 49 50 51 |
# File 'lib/ruflet/rails/resource_component.rb', line 48 def title(value = nil) @resource_title = value if value @resource_title || (model_name ? model_name.plural.humanize.titleize : "Resources") end |
Instance Method Details
#display_fields ⇒ Object
Columns rendered in the index table / list tiles.
99 100 101 |
# File 'lib/ruflet/rails/resource_component.rb', line 99 def display_fields resource_fields end |
#display_value(record, field) ⇒ Object
Formats a single field for display. Override for custom rendering.
104 105 106 |
# File 'lib/ruflet/rails/resource_component.rb', line 104 def display_value(record, field) record.public_send(field).to_s end |
#model_class ⇒ Object
— Resource configuration (override in the generated subclass) ——–
79 80 81 |
# File 'lib/ruflet/rails/resource_component.rb', line 79 def model_class self.class.model end |
#primary_label(record) ⇒ Object
— Index labels ——————————————————-
139 140 141 142 |
# File 'lib/ruflet/rails/resource_component.rb', line 139 def primary_label(record) field = display_fields.first field ? display_value(record, field) : "##{record_id(record)}" end |
#records ⇒ Object
— Record loading & persistence ————————————–
110 111 112 113 |
# File 'lib/ruflet/rails/resource_component.rb', line 110 def records scope = model_class.respond_to?(:limit) ? model_class.limit(50) : model_class.all scope.respond_to?(:limit) ? scope.limit(50) : scope.to_a.first(50) end |
#refresh ⇒ Object
Re-render the index after a create/update/destroy. The generated component calls this from its own (explicit) save/destroy code.
133 134 135 |
# File 'lib/ruflet/rails/resource_component.rb', line 133 def refresh render_index end |
#render_index ⇒ Object
115 116 117 118 119 |
# File 'lib/ruflet/rails/resource_component.rb', line 115 def render_index page.title = resource_title page.views = [] page.add(render) end |
#render_show(record) ⇒ Object
121 122 123 124 125 |
# File 'lib/ruflet/rails/resource_component.rb', line 121 def render_show(record) page.views = [] page.add(show(record)) page.update end |
#resource_fields ⇒ Object
Fields rendered on the detail (show) screen. The generated subclass overrides this with the scaffolded attributes; the default falls back to the model’s own attribute names.
94 95 96 |
# File 'lib/ruflet/rails/resource_component.rb', line 94 def resource_fields default_resource_fields end |
#resource_title ⇒ Object
83 84 85 |
# File 'lib/ruflet/rails/resource_component.rb', line 83 def resource_title self.class.title end |
#secondary_label(record) ⇒ Object
144 145 146 147 |
# File 'lib/ruflet/rails/resource_component.rb', line 144 def secondary_label(record) field = display_fields[1] field ? display_value(record, field) : nil end |
#show_record(record) ⇒ Object
127 128 129 |
# File 'lib/ruflet/rails/resource_component.rb', line 127 def show_record(record) render_show(record) end |
#singular_title ⇒ Object
87 88 89 |
# File 'lib/ruflet/rails/resource_component.rb', line 87 def singular_title model_class.respond_to?(:model_name) ? model_class.model_name.human.titleize : self.class.singular_title end |