0.0
No release in over 3 years
ElaineCrud provides a reusable BaseController and views to quickly generate CRUD interfaces for any ActiveRecord model with minimal configuration.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 3.0
~> 6.0
~> 2.10
~> 3.0
~> 2.1

Runtime

~> 4.0
~> 3.0
~> 1.2
>= 6.0
 Project Readme

ElaineCrud

A Rails engine for rapidly generating CRUD interfaces for ActiveRecord models with minimal configuration.

Image

Features

  • Zero Configuration: Works out of the box with any ActiveRecord model
  • Rails Conventions: Follows standard Rails patterns
  • Minimal Code: Just specify model and permitted params
  • Search & Filter: Built-in search across text fields
  • Sortable Columns: Click column headers to sort
  • Pagination: Automatic pagination with configurable page size
  • Export: Download data as CSV, Excel, or JSON
  • Extensible: Override any view or behavior in your host app
  • Modern UI: Clean, responsive interface with TailwindCSS
  • Inline Editing: Edit records in place with Turbo Frames

Installation

Add to your Gemfile:

gem 'elaine_crud'

Then run:

bundle install

Quick Start

1. Ensure you have ActiveRecord model representing your data.

bin/rails generate model Task title:string description:text priority:integer completed:boolean due_date:date
bin/rails db:migrate

2. Create a Controller for your ActiveRecord Model

Specify which layout ElaineCrud should use with the layout directive:

class TaskController < ElaineCrud::BaseController
  layout 'application'  # Use your app's layout (wraps ElaineCrud's content)

  model Task
  permit_params :title, :description, :priority, :completed, :due_date
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
Rails.application.routes.draw do
  resources :tasks
  root "tasks#index"
end

4. 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)

Here's an example layout file, which contains the critical stylesheet_link_tag for elaine_crud:

<!DOCTYPE html>
<html>
  <head>
    <title><%= content_for(:title) || "Taskmanager" %></title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag "elaine_crud", "data-turbo-track": "reload" %>
    <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
    <%= javascript_importmap_tags %>
  </head>

  <body class="bg-gray-100">
    <main class="w-full px-4 py-6">
      <%= yield %>
    </main>
  </body>
</html>

5. Start Your Server

bin/dev

Usage

Basic Controller

class TasksController < ElaineCrud::BaseController
  layout 'application'

  model Task
  permit_params :title, :description, :priority, :completed, :due_date
end

That's it - 6 lines of code for a full CRUD interface with search, sorting, pagination, and export.

DSL Reference

  • model(ModelClass) - Specify the ActiveRecord model to manage
  • permit_params(*attrs) - Define permitted attributes for strong parameters
  • field(field_name, **options) - Configure individual field display and behavior
  • default_sort(column:, direction:) - Set default sort column and direction (:asc or :desc)
  • disable_turbo - Disable Turbo Frames (use full-page navigation instead of inline editing)
  • show_view_button(enabled) - Show/hide the View button in actions column
  • max_export(limit) - Set maximum records for export (default: 10,000)

Requirements

  • Rails 7.0+
  • TailwindCSS (included via precompiled CSS)

Examples

More detailed example with customisations

A more comprehensive example showing custom field formatting, sorting, and relationships:

# app/controllers/products_controller.rb
class ProductsController < ElaineCrud::BaseController
  layout 'application'

  model Product
  permit_params :name, :description, :price, :stock_quantity, :category_id, :active

  # Sort by name alphabetically by default
  default_sort column: :name, direction: :asc

  # Show the View button in actions column
  show_view_button

  # Format price as currency
  field :price do |f|
    f.title "Price"
    f.display_as { |value, record| number_to_currency(value) if value.present? }
  end

  # Custom display for stock status
  field :stock_quantity do |f|
    f.title "Stock"
    f.display_as { |value, record|
      if value.to_i > 10
        content_tag(:span, "#{value} in stock", class: "text-green-600")
      elsif value.to_i > 0
        content_tag(:span, "Low: #{value}", class: "text-yellow-600 font-semibold")
      else
        content_tag(:span, "Out of stock", class: "text-red-600 font-semibold")
      end
    }
  end

  # Boolean with badge display
  field :active do |f|
    f.title "Status"
    f.display_as { |value, record|
      if value
        content_tag(:span, "Active", class: "px-2 py-1 text-xs rounded bg-green-100 text-green-800")
      else
        content_tag(:span, "Inactive", class: "px-2 py-1 text-xs rounded bg-gray-100 text-gray-600")
      end
    }
  end

  # Foreign key - automatically renders as dropdown in forms
  field :category_id do |f|
    f.foreign_key model: Category, display: :name
  end
end

Example Output

The generated interface includes:

  • Index Page: Responsive grid-based table with all records
  • Inline Editing: Click Edit to modify records in place (Turbo Frames)
  • Sortable Columns: Click headers to sort ascending/descending
  • Search: Filter records by text across searchable columns
  • Pagination: Navigate through large datasets with configurable page size
  • Export: Download as CSV, Excel (.xlsx), or JSON
  • Smart Formatting: Dates, booleans, and nil values formatted nicely
  • Action Buttons: Edit and Delete functionality
  • Empty States: Helpful messages when no records exist
  • Visual Feedback: Row highlights after saving changes

Example Controllers Reference

The test/dummy_app contains example controllers demonstrating various features:

Controller Features Demonstrated
LibrariesController has_many relationships (auto-detected), email as mailto link, date formatting
AuthorsController Boolean field with badge display, has_many relationship display, show_view_button
MembersController Enum-style field with colored badges, email links, date formatting
LibrariansController Role badges, salary as currency, email links
LoansController Multiple foreign_key fields, date sorting, status display
TagsController Color preview display, simple CRUD
BookCopiesController Minimal controller (just model and permit_params)
ProfilesController Minimal controller example
BooksController field with display_as, foreign_key, nested_create, currency formatting, custom calculate_layout for multi-row display, URL links

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
  ...
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

  1. Open a new issue and suggest a feature
  2. Fork the repository
  3. Create a feature branch
  4. Make your changes
  5. Add tests
  6. Submit a pull request

License

MIT License. See LICENSE for details.