ElaineCrud
A Rails engine for rapidly generating CRUD interfaces for ActiveRecord models with minimal configuration.
Features
- ✅ Zero Configuration: Works out of the box with any ActiveRecord model
- ✅ Minimal Code: Just specify model and permitted params
- ✅ Modern UI: Clean, responsive interface with TailwindCSS
- ✅ Extensible: Override any view or behavior in your host app
- ✅ Rails Conventions: Follows standard Rails patterns
Installation
Add to your Gemfile
:
gem 'elaine_crud'
Then run:
bundle install
Quick Start
1. Ensure Your Application Has a Layout
ElaineCrud is a content-only engine - it provides CRUD views but relies on your application to provide the HTML structure (layout, navigation, styling).
Your Rails app should have a layout file (typically app/views/layouts/application.html.erb
) that includes:
- Basic HTML structure (
<html>
,<head>
,<body>
) - TailwindCSS stylesheets
- JavaScript imports (including Turbo)
- Navigation/header/footer (optional, your choice)
Most Rails apps with TailwindCSS already have this. If not, ensure you have:
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<title>Your App</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
2. Create a Controller
Specify which layout ElaineCrud should use with the layout
directive:
class PeopleController < ElaineCrud::BaseController
layout 'application' # Use your app's layout (wraps ElaineCrud's content)
model Person
permit_params :name, :email, :phone, :active
end
Important: The layout 'application'
line tells ElaineCrud to render its CRUD views inside your application's layout. Without this, you'll see unstyled content with no HTML structure.
3. Add Routes
# config/routes.rb
resources :people
4. Add Stylesheet (Choose One Approach)
ElaineCrud offers two ways to handle styling:
Option A: Use Precompiled CSS (Easiest, Zero Config)
Add the precompiled stylesheet to your layout:
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<title>Your App</title>
<%= stylesheet_link_tag "elaine_crud", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
</head>
<body>
<%= yield %>
</body>
</html>
Pros: No Tailwind configuration needed, works immediately Cons: Cannot customize Tailwind theme
Option B: Scan ElaineCrud Sources (For Customization)
If you want to customize the Tailwind theme, add ElaineCrud's views to your tailwind.config.js
:
const path = require('path')
const execSync = require('child_process').execSync
// Get the gem path from bundler
const gemPath = execSync('bundle show elaine_crud', { encoding: 'utf-8' }).trim()
module.exports = {
content: [
'./app/views/**/*.html.erb',
'./app/helpers/**/*.rb',
'./app/assets/stylesheets/**/*.css',
'./app/javascript/**/*.js',
// Add ElaineCrud gem views and helpers
path.join(gemPath, 'app/views/**/*.html.erb'),
path.join(gemPath, 'app/helpers/**/*.rb')
],
theme: {
extend: {
// Your custom theme here
},
},
}
Pros: Full theme customization Cons: Requires Tailwind CSS build setup
5. Restart Your Server
rails server
Navigate to /people
and you'll have a fully functional CRUD interface!
Usage
Basic Controller
The minimal controller setup:
class ArticlesController < ElaineCrud::BaseController
layout 'application' # Host app controls layout (header/footer/styling)
model Article
permit_params :title, :content, :published
end
DSL Reference
-
model(ModelClass)
- Specify the ActiveRecord model to manage -
permit_params(*attrs)
- Define permitted attributes for strong parameters -
columns(config)
- (Future) Configure column display options
Customization
Override Views
Create views in your app with the same names to override engine views:
app/views/articles/index.html.erb # Overrides engine's index view
Override Controller Methods
class ArticlesController < ElaineCrud::BaseController
model Article
permit_params :title, :content, :published
private
# Custom record fetching with scoping
def fetch_records
Article.published.order(:title)
end
# Custom column selection
def determine_columns
%w[title published created_at]
end
end
Custom Helpers
Override the display helper in your application:
# app/helpers/application_helper.rb
def display_column_value(record, column)
case column
when 'published'
record.published? ? '📘 Published' : '📝 Draft'
else
super # Call the engine's helper
end
end
Requirements
- Rails 6.0+
- TailwindCSS (for styling)
Examples
Complete Example: Managing Blog Posts
# app/controllers/posts_controller.rb
class PostsController < ElaineCrud::BaseController
layout 'application' # Use your app's layout
model Post
permit_params :title, :content, :published, :category_id
private
def fetch_records
Post.includes(:category).order(created_at: :desc)
end
end
# config/routes.rb
resources :posts
# Navigate to /posts for instant CRUD interface
Example Output
The generated interface includes:
- Index Page: Responsive table with all records
- Smart Formatting: Dates, booleans, and nil values formatted nicely
- Action Buttons: Edit and Delete functionality
- Empty States: Helpful messages when no records exist
- Modern Styling: Clean TailwindCSS design
Architecture
ElaineCrud follows a separation of concerns approach:
- Engine provides: CRUD logic, data formatting, content templates
- Host app provides: Layout, styling, HTML structure, navigation
Layout Control
The gem doesn't impose any layout - your app controls the HTML structure:
class UsersController < ElaineCrud::BaseController
layout 'admin' # Use admin layout
# or layout 'public' # Use public layout
# or layout false # No layout (API mode)
model User
permit_params :name, :email
end
This means:
- ✅ Your app controls: Headers, footers, navigation, CSS frameworks
- ✅ Engine provides: Table content, buttons, data formatting
- ✅ Zero view files needed: No templates to create in your app
See ARCHITECTURE.md for detailed technical documentation.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
MIT License. See LICENSE for details.