Saved Views
Overviewâ
Saved Views let each user save the current state of an index page under a name and come back to it in one click. A view stores:
- Search and filters (standard and advanced)
- Sort
- Visible and hidden columns, including column order (Manage Columns)
- Records per page
- View type (
table,card,kanban)
Views are private to their owner (Current.user) and are scoped per model. Associated (tab) tables keep their own separate set of views.
Saved Views replace the old Index Preference feature (cm_index_preferences).
Setupâ
1. Run the generatorâ
rails generate cm_admin:ct_page_view
rails db:migrate
The migration:
- Enables the PostgreSQL
citextextension, so view names are case-insensitive. - Drops the legacy
cm_index_preferencestable if it exists. Its data is not migrated. - Creates
ct_page_views:
| Column | Type | Notes |
|---|---|---|
owner | polymorphic reference | Required. Set to Current.user |
name | citext | Required |
ar_model_name | string | Model whose index page the view belongs to |
associated_ar_model_name | string, default '' | Parent model when the view is on an associated tab |
visible_columns | string[] | Ordered |
hidden_columns | string[] | |
is_default | boolean | At most one per owner / model (partial unique index) |
view_type | integer enum | table: 0, card: 1, kanban: 2 |
records_per_page | integer, default 20 | |
filter_params | jsonb | Decoded filters hash |
sort_params | json |
See Generators.
2. Requirementsâ
DEFAULT_PER_PAGEmust be defined (it is generated inconfig/initializers/constants.rb).PER_PAGE_OPTIONSis optional and defaults to[10, 20, 50, 100].Current.usermust be set for admin requests.- PaperTrail must be set up.
CtPageViewuseshas_paper_trail.
There is no DSL to add: Saved Views appear on every index page and associated table.
Usageâ
| Action | How |
|---|---|
| Save a view | Set filters, sort, and columns, then Save View, enter a name, and Save |
| Apply a view | Saved Views, then click the view |
| Update a view | Apply it, then change filters, sort, columns, or page size. Changes are auto-saved to the active view |
| Clear the active view | Click Ă on the view button. This returns to the unfiltered page |
| Set as default | Use the âź menu, then Set as Default. The view opens automatically when you visit the page |
| Others | Use the âź menu: Copy Link, Edit (rename), Duplicate, Delete |
Default view behaviourâ
When a user opens an index page with no filters, current_ct_page_view_id, clear_filters, or clear_ct_page_view params, they are redirected to their default view. Links that already carry any of these params, such as shared filtered links, open as-is.
Shareable linksâ
A view applies itself through query params: current_ct_page_view_id, filters, sort, and view_type. Copy Link copies these params. Because views belong to their owner, other users only get the filters, sort, and view type from the link, not your saved columns.
Routesâ
These routes are added automatically for every cm-admin model, with no setup needed:
| Verb | Path | Action |
|---|---|---|
| GET | /<models>/ct_page_views | list_ct_page_view |
| POST | /<models>/ct_page_views | create_ct_page_view |
| PUT | /<models>/ct_page_views/:id | update_ct_page_view |
| DELETE | /<models>/ct_page_views/:id | destroy_ct_page_view |
| POST | /<models>/ct_page_views/:id/duplicate | duplicate_ct_page_view |
Route helpers follow the pattern <action>_ct_page_view_<model>_path, for example create_ct_page_view_user_path. The list route's helper is ct_page_view_<model>_path.
Working with CtPageView in Rubyâ
view = CtPageView.create!(
owner: user,
name: 'Active adults',
ar_model_name: 'User',
filter_params: { advanced: [{ filter_type: 'single_select', filter_name: 'status', condition: 'is', value: 'active' }] },
sort_params: { created_at: { dir: 'desc', type: nil } },
visible_columns: %w[name email status],
records_per_page: 50,
is_default: true
)
view.apply_params # => { current_ct_page_view_id: 1, filters: "eJy...", sort: { "created_at" => { ... } } }
view.apply_url # => index path with the params above
Setting is_default: true automatically unsets the previous default for the same owner, model, and associated model.
Upgrading from Index Preferenceâ
See the v8.2.0 upgrade guide.