Skip to main content

v8.0.3

Breaking Changes

FileImport and FileExport Models Renamed

The built-in FileImport and FileExport models have been renamed to CtFileImport and CtFileExport to avoid colliding with identically named models in host applications. Every public surface that used the old names has been renamed:

BeforeAfter
FileImport / FileExport modelsCtFileImport / CtFileExport
file_imports / file_exports tablesct_file_imports / ct_file_exports
CmAdmin::FileImport concernCmAdmin::CtFileImport
CmAdmin::FileExport concernCmAdmin::CtFileExport
FileImportPolicyCtFileImportPolicy
cm_*_file_import_path route helperscm_*_ct_file_import_path
cm_*_file_export_path route helperscm_*_ct_file_export_path
file_import[...] form/param keyct_file_import[...]
included_models = [FileImport, FileExport]included_models = [CtFileImport, CtFileExport]

Migration Steps

  1. Run the rename generator to create a migration for your application:
rails generate cm_admin:rename_file_import_and_export_tables
rails db:migrate

The generated migration renames file_imports to ct_file_imports and file_exports to ct_file_exports. It also rewrites stored model-name references in active_storage_attachments.record_type, versions.item_type, cm_permissions.ar_model_name, and cm_index_preferences.ar_model_name.

  1. Update config.included_models in config/initializers/zcm_admin.rb if you list the old constants:
# Before
config.included_models = [FileImport, FileExport]

# After
config.included_models = [CtFileImport, CtFileExport]
  1. Update any references in your application code:
    • Constant references: FileImport, FileExport, FileImportPolicy
    • Associations such as has_many :file_exports or belongs_to :file_import
    • Route helpers like cm_show_file_export_path or cm_index_file_import_path
    • Custom import forms or API clients that post a file_import[...] param key — the key is now ct_file_import[...]
    • Factories, seeds, or permission records that store FileImport/FileExport model names
note

The file_import: keyword argument on importer classes (initialize(file_import:)) and CmAdmin::BaseImporter's file_import reader are unchanged — only the model, table, route, and param names were renamed.

New Configuration

config.user_class — Configurable User Model

Hardcoded ::User references have been replaced with CmAdmin.config.user_class, which defaults to 'User'. If your application uses a different user model, set it in the initializer:

CmAdmin.configure do |config|
config.user_class = 'AdminUser'
# or
config.user_class = AdminUser
end

The value is lazily constantized, so it can be set before the model is loaded or after a Rails code reload.

It is used by the default user_lookup (OTP and password auth), the Trackable concern's created_by/updated_by associations, CmRole#users, CmEmailLog#triggered_by, CmSupportTicket associations and search, and the comments/mentions model.

Impact:

  • No action required if your user model is User.
  • If your app already overrides user_lookup for auth, consider setting user_class as well — other features (mentions, history, support tickets) read it independently of user_lookup.

Dependencies

Devise Is Now a Required Dependency

devise (>= 4.9) has moved from an opt-in extra to a required dependency and is loaded by the engine at boot (ostruct >= 0.6.0 was also added). Bundler installs it automatically, but note:

  • If your Gemfile pins devise below 4.9, relax the constraint.
  • Apps that don't use Devise still work — auth_method :custom remains available — but Devise will now be loaded in your process.

Internal Changes

Removed $available_actions Global Variable

CmAdmin::Model previously stored the model's action list in a process-wide global variable, $available_actions, while dynamically generating the model's controller and Pundit policy. The generated classes now use the model's own available_actions attribute, and the global variable is no longer set.

Impact:

  • No action required for standard applications — this is an internal refactor with no public API changes.
  • Removing the global fixes a subtle issue where $available_actions retained the last-initialized model's actions for the lifetime of the process and could be shared across models defined in the same process.
  • If your application references $available_actions directly (for example, in an initializer or monkey patch), read the model's available_actions attribute instead:
# Before
$available_actions

# After
CmAdmin::Model.find_by(name: 'User').available_actions