Core Module
The Core module (Plutonium::Core::Controller
) provides the foundational controller functionality that all Plutonium applications depend on. It's a lean, focused module that handles essential framework integration, URL generation, and controller bootstrapping.
TIP
The Core module is automatically included when you use Plutonium::Resource::Controller
or Plutonium::Portal::Controller
. You typically don't include it directly.
What the Core Module Provides
The Core module includes three essential controller concerns:
- Bootable: Package and engine detection with automatic view path configuration
- EntityScoping: Multi-tenancy support with entity-based scoping
- Authorizable: ActionPolicy integration for authorization
Core Controller Features
Smart URL Generation
The Core module provides intelligent URL generation that works with Plutonium's package system and entity scoping:
# Generate URLs for resources with proper routing context
resource_url_for(@user) # => "/users/1"
resource_url_for(@user, action: :edit) # => "/users/1/edit"
resource_url_for(User) # => "/users"
# Handle nested resources and packages
resource_url_for(@user, Post) # => "/users/1/posts"
resource_url_for(@post, parent: @user) # => "/users/1/posts/1"
# Build URL arguments for complex routing scenarios
args = resource_url_args_for(@user, Post)
# => {controller: "/users/posts", user_id: 1}
Enhanced Flash Messages
Extends Rails' default flash types with additional semantic types:
# Available flash types: :notice, :alert, :success, :warning, :error
redirect_to posts_path, success: "Post created successfully!"
redirect_to posts_path, warning: "Post saved with warnings"
redirect_to posts_path, error: "Failed to save post"
Helper Methods
The Core module provides several helper methods available in controllers and views:
# Page title management
set_page_title("Dashboard")
make_page_title("Users") # => "Users | App Name"
# Package and engine information
current_package # => AdminPortal (if in a package)
current_engine # => AdminPortal::Engine
# Resource registry access
registered_resources # => Array of registered resource classes
# Application branding
app_name # => Your application name
Package Integration (Bootable)
The Bootable concern automatically detects which package and engine a controller belongs to:
# In packages/admin_portal/app/controllers/users_controller.rb
class UsersController < ResourceController
# Automatically detects:
# current_package => AdminPortal
# current_engine => AdminPortal::Engine
# View paths automatically configured:
# - packages/admin_portal/app/views (prepended)
# - app/views (Rails default)
end
Automatic View Path Configuration
Each package gets its own view path automatically prepended:
# For AdminPortal::UsersController
# View lookup order:
# 1. packages/admin_portal/app/views/users/
# 2. packages/admin_portal/app/views/
# 3. app/views/users/
# 4. app/views/
Entity Scoping (Multi-tenancy)
The EntityScoping concern provides multi-tenancy support when configured:
# In your engine configuration
class AdminPortal::Engine < Rails::Engine
include Plutonium::Portal
# Enable entity scoping
scope_to_entity Organization, strategy: :path
end
Available Scoping Methods
When entity scoping is enabled:
# Check if scoped to an entity
scoped_to_entity? # => true/false
# Get current scoped entity
current_scoped_entity # => #<Organization id: 1>
# Get scoping configuration
scoped_entity_strategy # => :path
scoped_entity_param_key # => :organization_id
scoped_entity_class # => Organization
Entity Scoping Strategies
Path Strategy (most common):
# URLs include entity parameter: /organizations/1/users
scope_to_entity Organization, strategy: :path
Custom Strategy:
# Define your own scoping method
scope_to_entity Organization, strategy: :current_organization
private
def current_organization
current_user.organization
end
Authorization Integration (Authorizable)
The Authorizable concern integrates ActionPolicy for authorization:
# Authorization is automatically configured with:
authorize :user, through: :current_user
authorize :entity_scope, through: :entity_scope_for_authorize
# Helper methods available:
policy_for(@user) # Get policy for record
authorized_resource_scope(User) # Get authorized scope
Authorization Context
The Core module provides entity scoping context for authorization:
# In your policies, you can access:
class UserPolicy < ApplicationPolicy
def index?
# entity_scope is automatically available
user.admin? || entity_scope == user.organization
end
end
Framework Integration
ActiveStorage Integration
Automatically configures ActiveStorage URL options:
# Configured in before_action
ActiveStorage::Current.url_options = {
protocol: request.protocol,
host: request.host,
port: request.port
}
Layout Configuration
Sets up dynamic layout selection:
# Automatically uses 'resource' layout unless in Turbo Frame
layout -> { turbo_frame_request? ? false : "resource" }
Helper Integration
Includes all Plutonium helpers:
helper Plutonium::Helpers
# Includes: ApplicationHelper, AttachmentHelper, ContentHelper,
# DisplayHelper, TableHelper, TurboHelper, etc.
Usage Patterns
Basic Controller Setup
The Core module is typically used through other Plutonium modules:
# For resource controllers
class UsersController < ResourceController
include Plutonium::Resource::Controller
# Core module included automatically
end
# For portal controllers
class DashboardController < ResourceController
include Plutonium::Portal::Controller
# Core module included automatically
end
Direct Usage (Advanced)
If you need just the core functionality:
class CustomController < ApplicationController
include Plutonium::Core::Controller
def index
set_page_title("Custom Page")
# Core functionality available
end
end
Configuration
The Core module respects Plutonium's main configuration:
# config/initializers/plutonium.rb
Plutonium.configure do |config|
config.load_defaults 1.0
# These affect Core module behavior:
config.development = Rails.env.development?
config.cache_discovery = !Rails.env.development?
end
Best Practices
URL Generation
Always use resource_url_for
instead of Rails' url_for
for Plutonium resources:
# ✅ Good - respects packages and entity scoping
resource_url_for(@user)
# ❌ Avoid - doesn't understand Plutonium routing
user_url(@user)
Page Titles
Set page titles in controller actions for consistent branding:
def show
set_page_title(resource_record!.to_label)
# Automatically becomes "User Name | App Name"
end
Package Organization
Let the Bootable concern handle package detection automatically:
# ✅ Good - automatic detection
class AdminPortal::UsersController < ResourceController
# Package and engine automatically detected
end
# ❌ Avoid - manual configuration
class UsersController < ResourceController
def current_package
AdminPortal # Don't override unless necessary
end
end
Integration with Other Modules
- Resource Record - Builds on Core for full CRUD functionality
- Portal - Uses Core for multi-tenant portal applications
- Routing - Works with Core's URL generation methods
- Authorization - Integrates with Core's authorization system
The Core module provides a solid, focused foundation that other Plutonium modules build upon, handling the essential plumbing that makes the framework's conventions work seamlessly.