Module: CmAdmin::Models::DslMethod
Defined in lib/cm_admin/models/dsl_method.rb
Instance Method Summaryβ
| Method | Description |
|---|---|
action_group | Create a new group for actions. |
alert_box | Adds a new alert to the current section. |
all_db_columns | Get all DB columns for index layout automatically. |
bulk_action | Define a bulk action for selected records. |
cm_edit | Create the edit form page. |
cm_index | Create index/list page with pagination. |
cm_new | Create the βnew/createβ form page. |
cm_section | Define a layout section for forms/pages. |
cm_show | Create the detail/show page. |
cm_show_section | β οΈ Deprecated β use cm_section instead. |
column | Create a new column for index layout. |
custom_action | Define a custom action beyond CRUD. |
eager_load_associations | Preload associations to avoid N+1 queries. |
filter | Add filters to index/list page. |
kanban_view | Show index page as Kanban board view. |
page_description | Set page description. |
page_title | Set page title. |
row | Add a row wrapper for layout. |
scope_list | Add scopes for index action. |
sort_column | β οΈ Deprecated Set default sort column (deprecated). |
sort_direction | β οΈ Deprecated Set default sort direction (deprecated). |
sortable_columns | Configure sortable columns (preferred alternative). |
tab | Add tabs on show page, usually for associations. |
cm_indexβ
Create a table view for the index page with pagination.
Parametersβ
| Name | Type | Description |
|---|---|---|
display_name | String | The display name of the page. |
page_title | String | The title of the page. If not provided, defaults to the formatted model name pluralized. |
page_description | String | The description of the page. |
partial | String | The partial path to render for the page. |
view_type | Symbol | The type of index view. Allowed values: :table, :card, :kanban. Default: :table. |
Example β Basic index pageβ
cm_index do
page_title 'Post'
column :title
column :created_at, field_type: :date, format: '%d %b, %Y'
column :updated_at, field_type: :date, format: '%d %b, %Y', header: 'Last Updated At'
end
Display Types Supportedβ
| View Type | Usage |
|---|---|
:table | Default table layout with pagination. |
:card | Card-style layout (good for media-rich models). |
:kanban | Kanban-style board grouped by a status or field. |
Notesβ
cm_indexmust wrap all columns and filters meant for the index view.- If no
page_titleis given, it automatically becomes the pluralized resource name. - To build a Kanban index, use
view_type: :kanbantogether with akanban_viewdeclaration.
Method Signatureβ
cm_index(display_name: nil, page_title: nil, page_description: nil, partial: nil, view_type: :table)
cm_showβ
Create a view for the show page.
Parametersβ
| Name | Type | Description |
|---|---|---|
display_name | String | The display name of the page. |
page_title | String | Symbol | The title of the page. If a symbol is passed, it will be a method name on the model. |
page_description | String | The description of the page. |
partial | String | The partial path to render for the page. |
Example β Showing pageβ
cm_show page_title: :title do
tab :profile, '' do
cm_section 'Post Details' do
field :title
field :body, field_type: :rich_text
field :is_featured
field :status, field_type: :tag, tag_class: STATUS_TAG_COLOR
end
end
end
Method Signatureβ
cm_show(display_name: nil, page_title: nil, page_description: nil, partial: nil)
cm_editβ
Create a form for the edit action.
Parametersβ
| Name | Type | Description |
|---|---|---|
display_name | String | The display/button name of the page. |
page_title | String | Symbol | The title of the page, symbol will use a model method. |
page_description | String | Description of the page. |
partial | String | Partial path of the page. |
redirect_to | Proc, nil | Lambda to redirect after update. |
display_if | Proc | Lambda to conditionally display the form. |
Example β Editing page with redirectβ
cm_edit(display_name: 'Edit Post', page_title: "Edit Post", page_description: 'Enter all details to edit Post', redirect_to: ->(current_object) { "/pages/#{current_object.id}" }) do
cm_section 'Details' do
form_field :title, input_type: :string
form_field :body, input_type: :rich_text
end
end
Method Signatureβ
cm_edit(display_name: 'Edit', page_title: nil, page_description: nil, partial: nil, redirect_to: nil, display_if: ->(_arg) { true })
cm_newβ
Create a form for the new action.
Parametersβ
| Name | Type | Description |
|---|---|---|
display_name | String | The display/button name of the page. |
page_title | String | The title of the page. |
page_description | String | Description of the page. |
partial | String | Partial path of the page. |
redirect_to | Proc, nil | Lambda to redirect after create. |
allow_create_action | Proc | Lambda to control whether the Add button is shown. |
Example β Creating a new page with redirectβ
cm_new(display_name: 'Add Post', page_title: "Add Post", page_description: 'Enter all details to add Post', redirect_to: ->(current_object) { "/pages/#{current_object.id}" }) do
cm_section 'Details' do
form_field :title, input_type: :string
form_field :body, input_type: :rich_text
end
end
Method Signatureβ
cm_new(display_name: 'Add', page_title: nil, page_description: nil, partial: nil, redirect_to: nil, allow_create_action: -> { true })
page_titleβ
Set page title for the current action.
| Name | Type | Description |
|---|---|---|
title | String | Title of the page. |
Method Signatureβ
page_title(title)
page_descriptionβ
Set page description for the current action.
| Name | Type | Description |
|---|---|---|
description | String | Description of the page. |
Method Signatureβ
page_description(description)
kanban_viewβ
Set Kanban view for the current action.
| Name | Type | Description |
|---|---|---|
column_name | String | Name of the Kanban column. |
exclude | Array | Fields to exclude. |
only | Array | Fields to include. |
Method Signatureβ
kanban_view(column_name, exclude: [], only: [])
scope_listβ
Set scopes for the current action.
| Name | Type | Description |
|---|---|---|
scopes | Array | Array of scopes. |
Method Signatureβ
scope_list(scopes = [])
tabβ
Create a new tab on the show page.
Parametersβ
| Name | Type | Description |
|---|---|---|
tab_name | String | Symbol | Name of the tab. |
action_name | String | Name of the action. |
associated_model | String | Associated model name. |
layout_type | String | Layout type: cm_association_index or cm_association_show. |
layout | String | Layout of the tab. |
partial | String | Partial path of the tab. |
display_if | Proc | Lambda returning boolean to display tab. |
view_type | Symbol | View type: :table or :card. |
show_count | Boolean | Whether to show record count. Default: true. |
associated_model_name | String | Name of associated model if different from class name. |
Example β Creating a Tabβ
tab :comments, 'comment', associated_model: 'comments', layout_type: 'cm_association_index', show_count: true do
column :message
end
Method Signatureβ
tab(tab_name, action_name, associated_model: nil, layout_type: nil, layout: nil, partial: nil, display_if: nil, show_count: true, view_type: nil, associated_model_name: nil, allow_create_action: -> { true }, &block)
rowβ
Create a new row on a page or form.
| Name | Type | Description |
|---|---|---|
display_if | Proc | Lambda returning boolean to display row. |
html_attrs | Hash | HTML attributes for the row. |
Example β Conditional Row with Sectionβ
row(display_if: ->(current_object) { current_object.name == 'John' }, html_attrs: { class: 'row-class' }) do
cm_section 'Details' do
form_field :title, input_type: :string
end
end
Method Signatureβ
row(display_if: nil, html_attrs: nil, &block)
cm_sectionβ
Create a new section on a page or form.
| Name | Type | Description |
|---|---|---|
section_name | String | Name of section. |
display_if | Proc | Lambda returning boolean to display section. |
col_size | Integer | Column size in grid layout. |
html_attrs | Hash | HTML attributes for the section. |
partial | String | Partial path. |
dynamic_fields | Any | Dynamic fields. |
Example: Creating a sectionβ
cm_section('Basic Information', display_if: ->(current_object) { current_object.name == 'John' }, col_size: 6, html_attrs: { class: 'section-class' }) do
field :title, input_type: :string
end
Method Signatureβ
cm_section(section_name, display_if: nil, col_size: nil, html_attrs: nil, partial: nil, dynamic_fields: nil, &block)
cm_show_section (Deprecated)β
Use cm_section instead.
columnβ
Create a new column for index layout.
Parametersβ
| Name | Type | Description |
|---|---|---|
field_name | String | The name of the field. |
field_type | Symbol | The type of field. Can be :string, :text, :image, :date, :rich_text, :time, :integer, :decimal, :custom, :datetime, :money, :money_with_symbol, :link, :association, :enum, :tag, :attachment, or :drawer. |
header | String | The header of the field. |
format | String | The format of the field for date fields. |
helper_method | Symbol | The helper method for the field. Should be defined in custom_helper.rb and will take two arguments: record and field_name. |
export_method | Symbol | The export method for the field. Should be defined in the model and will take no arguments. |
height | Integer | The height of the field for image fields. |
width | Integer | The width of the field for image fields. |
custom_link | String | The custom link for the field. |
tag_class | Hash | Tag classes for the field. Example: { approved: 'completed', draft: 'active-two', rejected: 'danger' }. This will add a CSS class to the tag. |
display_if | Proc | A lambda that takes the current object and returns true or false. |
no_wrap | Boolean | Whether to wrap the content of the field or not. Default is false. |
Exampleβ
column('name', field_type: :string)
Method Signatureβ
column(field_name, options = {})
all_db_columnsβ
Get all database columns for a model for index layout.
| Name | Type | Description |
|---|---|---|
options | Hash | Options like exclude. |
Exampleβ
all_db_columns(exclude: ['id'])
Method Signatureβ
all_db_columns(options = {})
action_groupβ
Create a new group for actions.
| Name | Type | Description |
|---|---|---|
name | String | Group name. |
icon_name | String | FontAwesome icon. |
icon_style | String | CSS style for icon. |
Exampleβ
group 'Basic Information', icon_name: 'fa fa-list', icon_style: 'color: #000000' do
custom_action 'Edit', verb: 'get', display_type: :button, icon_name: 'fa fa-edit', icon_style: 'color: #000000' do
@posts = Post.all
end
end
Method Signatureβ
action_group(name, icon_name: 'fa fa-list', icon_style: nil)
custom_actionβ
Create a new custom action for model.
Parametersβ
| Name | Type | Description |
|---|---|---|
name | String | The name of the action. |
page_title | String | The title of the page. |
page_description | String | The description of the page. |
display_name | String | The display name of the action. |
verb | String | The HTTP verb of the action. Can be get, post, put, patch, or delete. |
layout | String | The layout of the action. |
layout_type | String | The layout type of the action. Can be cm_association_index or cm_association_show. |
partial | String | The partial path of the action. |
path | String | The path of the action. |
display_type | Symbol | The display type of the action. Can be :button, :modal, :form_modal, :form_page, :page, or :icon_only. |
modal_configuration | Hash | The configuration of the modal. |
url_params | Hash | The URL parameters of the action. |
display_if | Proc | A lambda that takes the current object and returns true or false. |
route_type | String | The route type of the action. Can be member or collection. |
icon_name | String | The icon name of the action, following Font Awesome icon names. |
icon_style | String | The icon style of the action, following Font Awesome style. Example: "--fa-primary-color: #fecb3e; --fa-secondary-color: #e63b7a;" |
group_name | String | The group name of the action. All actions with the same group name will be grouped together in a dropdown. |
alert_type | Symbol | The type of success alert to show. Choices are :flash and :banner. Only applies to success messages. |
Examplesβ
- Creating a custom action with modal
custom_action name: 'approve', route_type: 'member', verb: 'patch', icon_name: 'fa-regular fa-circle-check', path: ':id/approve', display_type: :modal, display_if: lambda(&:draft?), modal_configuration: { title: 'Approve Post', description: 'Are you sure you want approve this post', confirmation_text: 'Approve' } do
post = ::Post.find(params[:id])
post.approved!
post
end
- Creating a custom action with button
custom_action name: 'approve', route_type: 'member', verb: 'patch', icon_name: 'fa-regular fa-circle-check', path: ':id/approve', display_type: :button, display_if: lambda(&:draft?), group_name: 'my action' do
post = ::Post.find(params[:id])
post.approved!
post
end
- Creating a custom action with form modal and form page
custom_action name: 'change_password', route_type: 'member', verb: 'get', icon_name: 'fa-solid fa-key',
page_title: 'Change Password',
path: ':id/change_password', display_type: :form_modal do
form do
cm_section 'Password Details' do
form_field :username
form_field :age_group_id, input_type: :single_select, helper_method: :age_group_type_collection
form_field :cultural_background_ids, input_type: :multi_select, helper_method: :cultural_background_type_collection
form_field :language, input_type: :single_select, helper_method: :language_collection
end
end
on_submit do
@customer = ::Customer.find(params[:id])
@customer.update!(gender_id: params[:customer][:age_group_id])
@customer
end
end
Method Signatureβ
custom_action(name: nil, page_title: nil, page_description: nil, display_name: nil, verb: nil, layout: nil, layout_type: nil, partial: nil, path: nil, display_type: nil, redirect_to: nil, modal_configuration: {}, url_params: {}, display_if: ->(_) { true }, route_type: nil, icon_name: 'fa fa-th-large', icon_style: nil, group_name: nil, success_message: ->(_) { nil }, error_message: ->(_, _) { nil }, alert_type: :flash, &block)
bulk_actionβ
Create a new bulk action for a model.
Parametersβ
| Name | Type | Description |
|---|---|---|
name | String | The name of the action. |
display_name | String | The display name of the action. |
display_if | Proc | A lambda that takes the current object and returns true or false. |
redirection_url | String | The redirection URL of the action. |
icon_name | String | The icon name of the action, following Font Awesome icon names. |
verb | String | The HTTP verb of the action. Can be get, post, put, patch, or delete. |
display_type | Symbol | The display type of the action. Can be :page, :modal, :form_modal, :button, or :icon_only (deprecated). |
modal_configuration | Hash | The configuration of the modal. |
route_type | String | The route type of the action. Can be member or collection. |
partial | String | The partial path of the action. |
execution_mode | Symbol | The execution mode of the action. Can be :bulk or :individual (default :individual). |
alert_type | Symbol | The type of success alert to show. Choices are :flash and :banner. Only applies to success messages. |
- Supports
:individualor:bulkexecution mode andform_modalfor custom forms.
Examplesβ
- Creating a bulk action
bulk_action name: 'approve', display_name: 'Approve', display_if: lambda { |arg| arg.draft? }, redirection_url: '/posts', icon_name: 'fa-regular fa-circle-check', verb: :patch, display_type: :modal, modal_configuration: { title: 'Approve Post', description: 'Are you sure you want approve this post', confirmation_text: 'Approve' }, execution_mode: :individual do
posts = ::Post.where(id: params[:ids])
posts.each(&:approved!)
posts
end
- Creating a bulk action with form
bulk_action name: 'approve', display_name: 'Approve', display_if: lambda { |arg| arg.draft? }, redirection_url: '/posts', icon_name: 'fa-regular fa-circle-check', verb: :patch, display_type: :form_modal, modal_configuration: { title: 'Approve Post', confirmation_text: 'Approve' }, execution_mode: :individual do
form do
cm_section 'Comment' do
form_field :comment
end
end
on_submit do |id|
post = ::Post.find(id)
post.approved!
post
end
end
Method Signatureβ
bulk_action(name: nil, display_name: nil, display_if: ->(_) { true }, redirection_url: nil, icon_name: nil, verb: nil, display_type: nil, modal_configuration: {}, route_type: nil, partial: nil, icon_style: nil, execution_mode: :individual, success_message: ->(_arg) { nil }, error_message: ->(_arg) { nil }, alert_type: :banner, &block)
filterβ
Create a new filter for a model.
Parametersβ
| Name | Type | Description |
|---|---|---|
db_column_name | String | The name of the database column. |
filter_type | String | The type of filter. Can be :date, :multi_select, :range, :search, or :single_select. |
placeholder | String | The placeholder text for the filter. |
helper_method | String | The helper method for the filter. Should be defined in custom_helper.rb. |
filter_with | Symbol | Filter using the scope name on the model. |
active_by_default | Boolean | Make the filter active by default. |
collection | Array | The collection of values for the filter. Use with single_select or multi_select. |
default_value | Proc | A lambda providing the default value for the filter when no filter parameters are provided. |
Examplesβ
- Creating a filter
filter('name', :search)
filter('created_at', :date)
filter('status', :single_select, collection: ['draft', 'published'])
filter('status', :multi_select, helper_method: 'status_collection')
filter('age', :range)
- Creating a filter with default value lambda
filter('status', :single_select, collection: ['draft', 'published'], default_value: -> { 'draft' })
filter('category', :multi_select, collection: ['A', 'B', 'C'], default_value: -> { ['A', 'B'] })
filter('created_at', :date, default_value: -> { "#{30.days.ago.to_date} to #{Date.today}" })
filter('user_id', :single_select, helper_method: 'user_collection', default_value: -> { Current.user.id })
Method Signatureβ
filter(db_column_name, filter_type = nil, options = {})
sort_direction (β οΈ Deprecated)β
Set sort direction for filters. Use sortable_columns instead.
sort_column (β οΈ Deprecated)β
Set sort column for filters. Use sortable_columns instead.
alert_boxβ
Add an alert to the current section.
| Name | Type | Description |
|---|---|---|
header | String | Alert header. |
body | String | Alert body. |
type | Symbol | Type: :info, :success, :danger, :warning. |
partial | String | Custom partial path. |
display_if | Proc | Lambda to conditionally display alert. |
html_attrs | Hash | Custom HTML attributes. |
Examplesβ
- Basic info alert
alert_box(header: "Information", body: "This is an informational message.", type: :info)
- Basic info alert with custom body
alert_box(header: "Information", body: "This is an informational message. <br>This is a break text", type: :info)
- Alert with custom partial
alert_box(partial: "/users/sessions/alert", display_if: ->(arg) { arg.present? })
- Alert with conditional display and custom HTML attributes
alert_box(header: "Warning", body: "Please review your submission.", type: :warning, display_if: ->(user) { user.submissions.any?(&:incomplete?) }, html_attrs: { id: "submission-warning", data: { turbo_frame: "warnings" } }
)
NOTE: Alerts cannot be placed inside nested sections. If added within a nested section, the alert will appear on the wrapped cm_show_section.
NOTE: Only the specified types (info, success, danger, warning) are supported. Any other type will default to a standard div.
Adding Alert For more information on how to add alerts to your model.
Method Signatureβ
alert_box(header: nil, body: nil, type: nil, icon_name: nil, partial: nil, display_if: ->(_arg) { true }, html_attrs: {})
sortable_columnsβ
Configure sortable columns for a model.
Parametersβ
Note: Default sort direction will be ascending.
| Name | Type | Description |
|---|---|---|
columns | Array | An array of hashes defining the columns and display names for sorting. |
Options inside Hashβ
| Name | Type | Description |
|---|---|---|
:column | String | The database column name. |
:display_name | String | The display name for the sort option. |
:default | Boolean | Whether this is the default sort column. |
:default_direction | String | Default sort direction. Can be 'asc' or 'desc'. Default is 'asc'. |
:sort_datatype | String | The SQL datatype for JSONB columns (e.g., 'TIMESTAMP', 'INTEGER'). |
:sort_with | Symbol | Custom scope method name on the model for custom sorting logic. |
:display_if | Proc | Condition to display this sort option. |
Examplesβ
- Sortable Columns
sortable_columns([{column: 'id', display_name: 'ID'},
{column: 'updated_at', display_name: 'Last Updated At'}])
- Sortable Columns with default column and direction verified_at is a JSONB column, so we need to specify the sort_datatype
sortable_columns([{column: 'id', display_name: 'ID', default: true, default_direction: 'desc'},
{column: 'updated_at', display_name: 'Last Updated At'},
{column: 'verified_at', display_name: 'Verified At', sort_datatype: 'TIMESTAMP'}])
- Sortable Columns with display_if condition
sortable_columns([{column: 'id', display_name: 'ID'},
{column: 'created_at', display_name: 'Created At', display_if: ->(obj) { current_user.admin? }}])
- Sortable Columns with custom sort logic
sortable_columns([{column: 'request_due_date', display_name: 'Request Due Date', sort_with: :sort_by_due_date_nulls_first}])
Note: In you model define a scope sort_by_due_date_nulls_first
Method Signatureβ
sortable_columns(columns)
eager_load_associationsβ
Configure eager loading for an action to avoid N+1 queries.
| Name | Type | Description |
|---|---|---|
associations | Array | List of association names to eager load. |
Exampleβ
eager_load_associations [:association_name]
eager_load_associations [:constant]
Method Signatureβ
eager_load_associations(associations = [])