Class: IronAdmin::Resource
- Inherits:
-
Object
- Object
- IronAdmin::Resource
- Includes:
- Concerns::Importable, Concerns::LiveUpdatable, Concerns::Nestable, Concerns::SoftDeletable
- Defined in:
- lib/iron_admin/resource.rb
Overview
Base class for defining admin resources in IronAdmin.
Resources are the primary way to configure how models appear in the admin panel. Each resource corresponds to a model and provides a DSL for customizing fields, filters, actions, search, and authorization.
Class Method Summary collapse
-
.action(name, form_fields: [], **options) {|record| ... } ⇒ void
Defines a custom action for individual records.
-
.action_allowed?(action_name) ⇒ Boolean
Checks if a CRUD action is allowed (not denied via deny_actions).
-
.action_field(name) ⇒ IronAdmin::ActionField
Convenience constructor for ActionField instances.
-
.adapter ⇒ IronAdmin::Adapters::Base
Returns the adapter instance for this resource's model.
-
.all_filters ⇒ Array<Hash>
Returns all filters (auto-inferred + manually defined).
-
.all_scopes ⇒ Array<Hash>
Returns all scopes with user-defined scopes first, soft delete scopes last.
-
.auto_inferred_filters ⇒ Array<Hash>
private
Returns filters automatically inferred from enum columns and database column types.
-
.belongs_to(name, **options) ⇒ void
Declares a belongs_to association for this resource.
-
.bulk_action(name, form_fields: [], **options) {|records| ... } ⇒ void
Defines a bulk action for multiple selected records.
-
.component(name, klass) ⇒ void
Registers a custom component class to override default rendering.
-
.deny_actions(*actions) ⇒ void
Disables specific CRUD actions for this resource.
-
.display_attribute ⇒ Symbol
Returns the attribute used to display individual records.
-
.export_fields(*fields) ⇒ void
Specifies which fields appear in exports.
-
.exports(*formats) ⇒ void
Configures which export formats are available.
-
.field(name, **options) ⇒ void
Configures display and behavior options for a field.
-
.filter(name, **options) ⇒ void
Defines a filter for the resource index page.
-
.form_fields(*fields) ⇒ void
Specifies which fields appear on create/edit forms.
-
.habtm_associations ⇒ Array<Hash>
Returns HABTM association configurations for multi-select on forms and badge display.
-
.has_and_belongs_to_many(name, **options) ⇒ void
Declares a has_and_belongs_to_many association for this resource.
-
.has_many_associations ⇒ Array<Hash>
Returns has_many association configurations for related lists.
-
.has_one_associations ⇒ Array<Hash>
Returns has_one association configurations for display on show pages.
-
.index_fields(*fields) ⇒ void
Specifies which fields appear on the index (list) page.
-
.inherited(subclass) ⇒ Object
private
Automatically registers subclasses with the ResourceRegistry.
-
.label ⇒ String
Returns the human-readable label for this resource.
-
.menu(**options) ⇒ void
Configures the sidebar menu appearance for this resource.
-
.model ⇒ Class
Returns the ActiveRecord model class for this resource.
-
.policy { ... } ⇒ void
Defines the authorization policy for this resource.
-
.preload(*associations) ⇒ void
Specifies which associations to preload on queries.
-
.preload_associations ⇒ Array<Symbol>
Returns associations to preload for index/show queries.
-
.remove_filter(name) ⇒ void
Removes a filter (useful for removing auto-generated enum filters).
-
.reset_resource_policy! ⇒ Object
private
Clears the cached policy (used in testing).
-
.resolved_fields ⇒ Array<IronAdmin::Field>
Returns Field objects for all fields, with overrides applied.
-
.resource_name ⇒ String
Returns the URL-friendly resource name (pluralized model name).
-
.resource_policy ⇒ IronAdmin::Policy?
Returns the Policy instance for this resource.
-
.scope(name, lambda, default: false) ⇒ void
Defines a named scope for filtering records on the index page.
-
.searchable(*columns) ⇒ void
Specifies which columns are searchable via the search box.
-
.searchable_columns ⇒ Array<Symbol>
Returns the list of searchable column names.
-
.unsearchable(*columns) ⇒ void
Excludes columns from the default searchable set.
Class Method Details
.action(name, form_fields: [], **options) {|record| ... } ⇒ void
This method returns an undefined value.
Defines a custom action for individual records.
Actions appear in the actions dropdown on show and index pages. They execute arbitrary code when triggered.
315 316 317 318 |
# File 'lib/iron_admin/resource.rb', line 315 def action(name, form_fields: [], **, &block) coerced = coerce_action_fields(form_fields) self.defined_actions = defined_actions + [{ name: name, block: block, form_fields: coerced, ** }] end |
.action_allowed?(action_name) ⇒ Boolean
Checks if a CRUD action is allowed (not denied via deny_actions).
496 497 498 |
# File 'lib/iron_admin/resource.rb', line 496 def action_allowed?(action_name) denied_crud_actions.exclude?(action_name.to_sym) end |
.action_field(name) ⇒ IronAdmin::ActionField
Convenience constructor for ActionField instances.
364 365 366 |
# File 'lib/iron_admin/resource.rb', line 364 def action_field(name, **) ActionField.new(name: name, **) end |
.adapter ⇒ IronAdmin::Adapters::Base
Returns the adapter instance for this resource's model.
The adapter provides a uniform interface for schema introspection, query building, and CRUD operations regardless of the underlying data source (ActiveRecord, Mongoid, HTTP, etc.).
Defensively re-resolves when the cached @adapter doesn't match
the currently configured adapter_class. This catches the case
where the eager Resource.inherited flow memoized an
Adapters::ActiveRecord built before the subclass body's
self.adapter_class = :mongoid (or :http) took effect.
94 95 96 97 98 |
# File 'lib/iron_admin/resource.rb', line 94 def adapter wanted = resolve_adapter_class @adapter = nil if @adapter && !@adapter.instance_of?(wanted) @adapter ||= wanted.new(model) end |
.all_filters ⇒ Array<Hash>
Returns all filters (auto-inferred + manually defined).
258 259 260 |
# File 'lib/iron_admin/resource.rb', line 258 def all_filters auto_inferred_filters + defined_filters end |
.all_scopes ⇒ Array<Hash>
Returns all scopes with user-defined scopes first, soft delete scopes last.
265 266 267 |
# File 'lib/iron_admin/resource.rb', line 265 def all_scopes defined_scopes + _soft_delete_scopes end |
.auto_inferred_filters ⇒ Array<Hash>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns filters automatically inferred from enum columns and database column types.
String/text columns auto-infer as :string filters. Integer/float/decimal columns auto-infer as :number filters. Enum columns auto-infer as :select filters.
250 251 252 253 |
# File 'lib/iron_admin/resource.rb', line 250 def auto_inferred_filters enum_filters = enum_auto_filters enum_filters + infer_column_filters(enum_filters) end |
.belongs_to(name, **options) ⇒ void
This method returns an undefined value.
Declares a belongs_to association for this resource.
Used to configure how the association is displayed and which resource to link to.
547 548 549 |
# File 'lib/iron_admin/resource.rb', line 547 def belongs_to(name, **) self.defined_associations = defined_associations.merge(name => { kind: :belongs_to, ** }) end |
.bulk_action(name, form_fields: [], **options) {|records| ... } ⇒ void
This method returns an undefined value.
Defines a bulk action for multiple selected records.
Bulk actions appear in the bulk actions dropdown when records are selected on the index page. All records are processed in a single database transaction.
345 346 347 348 |
# File 'lib/iron_admin/resource.rb', line 345 def bulk_action(name, form_fields: [], **, &block) coerced = coerce_action_fields(form_fields) self.defined_bulk_actions = defined_bulk_actions + [{ name: name, block: block, form_fields: coerced, ** }] end |
.component(name, klass) ⇒ void
This method returns an undefined value.
Registers a custom component class to override default rendering.
436 437 438 |
# File 'lib/iron_admin/resource.rb', line 436 def component(name, klass) self.component_overrides = component_overrides.merge(name => klass) end |
.deny_actions(*actions) ⇒ void
This method returns an undefined value.
Disables specific CRUD actions for this resource.
This is a simpler alternative to policies when you want to completely disable actions for all users.
488 489 490 |
# File 'lib/iron_admin/resource.rb', line 488 def deny_actions(*actions) self.denied_crud_actions = actions.map(&:to_sym) end |
.display_attribute ⇒ Symbol
Returns the attribute used to display individual records.
Checks for common display methods (name, title, email, etc.) and falls back to :id if none found.
697 698 699 700 701 |
# File 'lib/iron_admin/resource.rb', line 697 def display_attribute ApplicationHelper::DISPLAY_METHODS.find do |method| adapter.has_column?(method) end || :id end |
.export_fields(*fields) ⇒ void
This method returns an undefined value.
Specifies which fields appear in exports.
By default, exports include all visible fields.
528 529 530 |
# File 'lib/iron_admin/resource.rb', line 528 def export_fields(*fields) self.export_field_names = fields end |
.exports(*formats) ⇒ void
This method returns an undefined value.
Configures which export formats are available.
By default, both :csv and :json exports are enabled. Call with no arguments to disable all exports.
514 515 516 |
# File 'lib/iron_admin/resource.rb', line 514 def exports(*formats) self.export_formats = formats end |
.field(name, **options) ⇒ void
This method returns an undefined value.
Configures display and behavior options for a field.
Fields are automatically inferred from the model's database schema. Use this method to override the inferred configuration.
155 156 157 |
# File 'lib/iron_admin/resource.rb', line 155 def field(name, **) self.field_overrides = field_overrides.merge(name => ) end |
.filter(name, **options) ⇒ void
Enum columns automatically get select filters generated. Use remove_filter to remove auto-generated filters.
This method returns an undefined value.
Defines a filter for the resource index page.
Filters appear in the filter bar and allow users to narrow down the displayed records.
226 227 228 |
# File 'lib/iron_admin/resource.rb', line 226 def filter(name, **) self.defined_filters = defined_filters + [{ name: name, ** }] end |
.form_fields(*fields) ⇒ void
This method returns an undefined value.
Specifies which fields appear on create/edit forms.
By default, shows all editable fields. Use this to customize which fields appear and in what order.
394 395 396 |
# File 'lib/iron_admin/resource.rb', line 394 def form_fields(*fields) self.form_field_names = fields end |
.habtm_associations ⇒ Array<Hash>
Returns HABTM association configurations for multi-select on forms and badge display.
666 667 668 669 670 671 672 673 674 675 676 677 |
# File 'lib/iron_admin/resource.rb', line 666 def habtm_associations defined_associations.filter_map do |assoc_name, config| next unless config[:kind] == :has_and_belongs_to_many reflection = adapter.association(assoc_name) next unless reflection resource = resolve_association_resource(config, reflection) { name: assoc_name, reflection: reflection, resource: resource, **config.except(:kind, :resource) } end end |
.has_and_belongs_to_many(name, **options) ⇒ void
This method returns an undefined value.
Declares a has_and_belongs_to_many association for this resource.
HABTM associations appear as multi-select checkboxes on forms and as badge lists on show pages.
579 580 581 |
# File 'lib/iron_admin/resource.rb', line 579 def has_and_belongs_to_many(name, **) # rubocop:disable Naming/PredicatePrefix self.defined_associations = defined_associations.merge(name => { kind: :has_and_belongs_to_many, ** }) end |
.has_many_associations ⇒ Array<Hash>
Returns has_many association configurations for related lists.
632 633 634 635 636 637 638 639 640 641 642 643 644 |
# File 'lib/iron_admin/resource.rb', line 632 def has_many_associations defined_associations.filter_map do |assoc_name, config| next unless config[:kind] == :has_many reflection = adapter.association(assoc_name) next unless reflection resource = resolve_association_resource(config, reflection) next unless resource { name: assoc_name, reflection: reflection, resource: resource, **config.except(:kind, :resource) } end end |
.has_one_associations ⇒ Array<Hash>
Returns has_one association configurations for display on show pages.
649 650 651 652 653 654 655 656 657 658 659 660 661 |
# File 'lib/iron_admin/resource.rb', line 649 def has_one_associations # rubocop:disable Naming/PredicatePrefix defined_associations.filter_map do |assoc_name, config| next unless config[:kind] == :has_one reflection = adapter.association(assoc_name) next unless reflection resource = resolve_association_resource(config, reflection) next unless resource { name: assoc_name, reflection: reflection, resource: resource, **config.except(:kind, :resource) } end end |
.index_fields(*fields) ⇒ void
This method returns an undefined value.
Specifies which fields appear on the index (list) page.
By default, shows the first 6 fields. Use this to customize which fields appear and in what order.
379 380 381 |
# File 'lib/iron_admin/resource.rb', line 379 def index_fields(*fields) self.index_field_names = fields end |
.inherited(subclass) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Automatically registers subclasses with the ResourceRegistry.
71 72 73 74 75 76 77 78 79 |
# File 'lib/iron_admin/resource.rb', line 71 def inherited(subclass) super return if subclass.name.nil? begin IronAdmin::ResourceRegistry.register(subclass) rescue NameError end end |
.label ⇒ String
Returns the human-readable label for this resource.
687 688 689 |
# File 'lib/iron_admin/resource.rb', line 687 def label adapter.human_name.pluralize end |
.menu(**options) ⇒ void
This method returns an undefined value.
Configures the sidebar menu appearance for this resource.
414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/iron_admin/resource.rb', line 414 def (**) if .key?(:section) legacy = .delete(:section) # Preserve `:group` precedence based on key presence so that # explicitly passing `group: nil` (or `group: false`) still # wins over `section:`. Using `||=` would clobber falsey # explicit values. [:group] = legacy unless .key?(:group) end self. = end |
.model ⇒ Class
Returns the ActiveRecord model class for this resource.
By default, infers the model from the resource class name (e.g., UserResource -> User).
119 120 121 122 123 124 |
# File 'lib/iron_admin/resource.rb', line 119 def model return model_class_override if model_class_override return Adapters::Http::ModelProxy.new(self) if adapter_class == :http name.sub(/Resource\z/, "").sub(/\AIronAdmin::Resources::/, "").constantize end |
.policy { ... } ⇒ void
This method returns an undefined value.
Defines the authorization policy for this resource.
Policies control which actions users can perform. Without a policy, all actions are allowed by default.
457 458 459 |
# File 'lib/iron_admin/resource.rb', line 457 def policy(&block) self._policy_block = block end |
.preload(*associations) ⇒ void
This method returns an undefined value.
Specifies which associations to preload on queries.
Use this to optimize queries by eager loading associations.
625 626 627 |
# File 'lib/iron_admin/resource.rb', line 625 def preload(*associations) @preload_associations = associations end |
.preload_associations ⇒ Array<Symbol>
Returns associations to preload for index/show queries.
By default, preloads all belongs_to associations to avoid N+1 queries. Use preload to customize.
611 612 613 |
# File 'lib/iron_admin/resource.rb', line 611 def preload_associations @preload_associations || infer_preload_associations end |
.remove_filter(name) ⇒ void
This method returns an undefined value.
Removes a filter (useful for removing auto-generated enum filters).
238 239 240 |
# File 'lib/iron_admin/resource.rb', line 238 def remove_filter(name) self.defined_filters = defined_filters.reject { |f| f[:name] == name } end |
.reset_resource_policy! ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Clears the cached policy (used in testing).
472 473 474 |
# File 'lib/iron_admin/resource.rb', line 472 def reset_resource_policy! remove_instance_variable(:@resource_policy) if defined?(@resource_policy) end |
.resolved_fields ⇒ Array<IronAdmin::Field>
Returns Field objects for all fields, with overrides applied.
Merges auto-inferred fields from the database schema with any customizations made via field and association declarations.
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
# File 'lib/iron_admin/resource.rb', line 589 def resolved_fields inferred = FieldInferrer.call(adapter) inferred.map do |field| overrides = field_overrides[field.name] || {} assoc_overrides = defined_associations[field.name] || {} merged = assoc_overrides.except(:kind).merge(overrides) if merged.any? Field.new(field.name, type: field.type, **field., **merged) else field end end end |
.resource_name ⇒ String
Returns the URL-friendly resource name (pluralized model name).
682 |
# File 'lib/iron_admin/resource.rb', line 682 delegate :resource_name, to: :adapter |
.resource_policy ⇒ IronAdmin::Policy?
Returns the Policy instance for this resource.
464 465 466 467 468 |
# File 'lib/iron_admin/resource.rb', line 464 def resource_policy return @resource_policy if defined?(@resource_policy) @resource_policy = Policy.new(&_policy_block) if _policy_block end |
.scope(name, lambda, default: false) ⇒ void
This method returns an undefined value.
Defines a named scope for filtering records on the index page.
Scopes appear as tabs above the data table and allow quick filtering to predefined subsets of records.
286 287 288 |
# File 'lib/iron_admin/resource.rb', line 286 def scope(name, lambda, default: false) self.defined_scopes = defined_scopes + [{ name: name, scope: lambda, default: default }] end |
.searchable(*columns) ⇒ void
This method returns an undefined value.
Specifies which columns are searchable via the search box.
By default, all string and text columns are searchable (except those ending in _digest). Use this to explicitly define searchable columns.
170 171 172 |
# File 'lib/iron_admin/resource.rb', line 170 def searchable(*columns) self._searchable_columns = columns end |
.searchable_columns ⇒ Array<Symbol>
Returns the list of searchable column names.
If searchable was called, returns those columns. Otherwise, returns all string/text columns except those ending in _digest and those excluded via unsearchable.
196 197 198 199 200 201 202 203 |
# File 'lib/iron_admin/resource.rb', line 196 def searchable_columns return _searchable_columns if _searchable_columns adapter.columns.select { |c| c.type.in?(%i[string text]) } .map { |c| c.name.to_sym } .reject { |name| name.to_s.end_with?("_digest") } .reject { |name| _unsearchable_columns.include?(name) } end |
.unsearchable(*columns) ⇒ void
This method returns an undefined value.
Excludes columns from the default searchable set.
Use this when you want to keep most auto-inferred columns but exclude specific ones.
185 186 187 |
# File 'lib/iron_admin/resource.rb', line 185 def unsearchable(*columns) self._unsearchable_columns = _unsearchable_columns + columns.map(&:to_sym) end |