Scaffolding a CRUD Resource
ruflet_rails extends the standard Rails scaffold generator. When you generate a Rails scaffold, it also creates a complete Ruflet CRUD component using the same model name and attributes. The generated component is ordinary application code that you own and can edit.
It includes the index table and compact list, detail screen, create/edit dialog, delete confirmation, form controls, and the calls that save and delete records.
Generate
bin/rails generate scaffold Post title:string body:text published_on:date
This creates one component:
app/views/ruflet/components/posts/post_component.rb
The normal Rails scaffold generator creates its usual model, controller, views, migration, and routes. Ruflet adds only the resource component shown above.
To generate a Rails scaffold without its Ruflet component:
bin/rails generate scaffold Post title:string --skip-ruflet
Mount the component
Mount the generated component explicitly in config/routes.rb:
mount Ruflet::Rails.web_app(view: "PostComponent"), at: "/posts"
The mount serves the Ruflet web client and connects it to PostComponent. The model is inferred from the component class name: PostComponent uses Post.
What the generated file contains
The generated file contains the complete resource UI and persistence behavior. The version in ruflet_demo includes methods such as:
renderfor the responsive index screenshow(record)for the detail screenrecord_table,table_columns, andtable_rowfor larger screensrecord_listandrecord_tilefor compact screensopen_form(record)for creating and editing recordsopen_delete(record)for delete confirmationfield_rowand header helpers for the generated layout
The create/edit and delete operations are explicit inside the generated dialog button handlers:
filled_button(content: text("Save"), on_click: ->(_event) {
if record.update(attributes.call)
close_dialog(dialog)
refresh
show_snackbar("#{singular_title} saved")
else
show_errors(record)
end
})
filled_button(content: text("Delete"), on_click: ->(_event) {
record.destroy!
close_dialog(dialog)
refresh
show_snackbar("#{singular_title} deleted")
})
Change these generated handlers when your application needs authorization, service objects, custom validations, or different UI.
What ResourceComponent provides
PostComponent inherits reusable helpers from Ruflet::Rails::ResourceComponent:
- Model and title inference through
model_class,resource_title, andsingular_title - Record loading through
records - Field inference and formatting through
resource_fields,display_fields, anddisplay_value - Index/detail navigation through
render_index,render_show,show_record, andrefresh - Responsive sizing, dialogs, snackbars, errors, and date/time picker helpers
The generated component uses these helpers, but does not normally redefine them. Override a helper in your component only when its default behavior does not fit your model.
For example, customize the table columns and displayed values like this:
class PostComponent < Ruflet::Rails::ResourceComponent
def display_fields
%w[title published_on]
end
def display_value(record, field)
return record.published_on&.to_fs(:long) if field == "published_on"
super
end
end
Reading control values
Inside the generated form, read picker and field values using dot access:
title_control.value
date_control.value
range_control.start_value
range_control.end_value
Controls also support control.value = value and control[:value].
Generated input types
The attribute type determines the generated form control:
stringandtextuse text fieldsbooleanuses a checkboxdateuses a date pickerdatetimeandtimeuse a time pickerdaterangeuses a date range picker
Generated form inputs stretch to the dialog width. Date and time pickers opened from the form are handled as nested dialogs and return to the form after selection.