Create fancy tables from ActiveRecord::Relations which are semantic HTML5, are easy to style, and are beautiful.
Ruby CSS JavaScript
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Tables. Done right.


<%= fancy_table @firefly_episodes %>

fancy_table of Firefly episodes

Okay, you've piqued my interest. What's going on here?

fancy_table allows you to easily turn an ActiveRecord::Relation into a semantic HTML5 table which supports sorting, pagination, and links for actions to be posted back to the controller.

Besides automagic generation of the table from the ActiveRecord::Relation, the killer feature is probably sorting on the server-side (read: vroom!). This is done by clicking on headers and uses SmartOrder (see below).

If it's so easy, how do I do it?

Great question. A lot of effort was put into making the developer—that's you—happy. To that end, much of fancy_table's syntax had been wrapped into two calls.

In the controller:

def index
  @firefly_episodes = FireflyEpisode.scoped
  @firefly_episodes = build_fancy_table @firefly_episodes

Then in a view:

= fancy_table @firefly_episodes

What if I want to do...

We've probably got you covered. Let's take a look at the optional arguments for build_fancy_table in the controller, and their default values.


Actions appear in the fancy_table's <caption> as links. Actions are useful for things which do not relate to specific objects, such as creating a new entry.

The format fairly simple:

actions: { "Link text" => path }


Member Actions appear as links in the row with the model in the last <td>. These should be used for object-specific actions, such as edit or delete.

Simple actions can be formatted similarly to the actions option above:

member_actions: { "edit" => :edit }

Which will render a link to edit_model_path.

You can also pass a block as the value for more complicated actions:

member_actions: { "complicated" => block_of_code }

def block_of_code(member)
  # Return a URL

By default there are no member_actions.


Group actions are a little different than the other options. They require a method on the update_multiple_controller (this option defaults to the controller displaying the fancy_table, so most of the time you're probably set) called update_multiple. Let's take a look at what that should look like.

def update_multiple
  @models = Model.find(params[:model_ids])
  case params[:commit] # params[:commit] will contain the group_action
  when group_actions[0] # You'd probably have something like 'Approve Selected'
                        #   or 'Delete Selected' here
    @models.each do |model|
      # Do whatever is required for this group action
  when group_actions[n]
    @models.each do |model|
      # Do whatever is required for this group action
  # redirect to wherever you'd like your user to go next

You can set a custom update multiple controller:

update_multiple_controller: UpdateMultipleController

The format for group_actions is:

group_actions: [:delete, :approve, :etc]


The number of rows to show on the fancy_table at a time. Pagination will be added to the <footer> if neccessary.

Pagination magic provided by kaminari

I don't like how it looks.

Sticks and stones, friend.

While we've included styles for fancy_table, we encourage you to roll your own that match your site. It will probably turn out better for you in the long run if you design your own look‐and‐feel.

We customized the styles for fancy_table for our own site. Here is what the previous table would look like for us:

fancy_table of Firefly episodes


The heavy lifting of sorting fancy_tables is done server-side in the model. To accomplish this, we include the SmartOrder module in our models.

You have a couple of options here. If you plan to use fancy_table extensively through your application, you can include SmartOrder in ActiveRecord::Base in an initializer:

class ActiveRecord::Base
  include SmartOrder::Sortable

If you are only going to use fancy_table in one or two places—or if you don't like the idea of extending Rails core classes, you can include it in specific models as well:

class Book < ActiveRecord::Base
  include SmartOrder::Sortable
  # The rest of your model code

We plan to pull smart_order out into its own gem down the road, but we were more excited about fancy_table so we started here.

Our own dog food

We use fancy_table extensively in our solar project finance platform, SolMarket, and plan to use it in the Rails rewrite of our other site, SolSystems.

We love you...

...and want you to be happy.

If you have any problems with fancy_table, please open an issue and we'll see if we can help out.

We'd love you more even more if you forked fancy_table and opened a pull request instead.