Skip to content
This repository


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Components for Rails.

Fetching latest commit…


Cannot retrieve the latest commit at this time

Octocat-spinner-32 lib
Octocat-spinner-32 rails_generators
Octocat-spinner-32 test
Octocat-spinner-32 .gitignore
Octocat-spinner-32 CHANGES
Octocat-spinner-32 Gemfile
Octocat-spinner-32 MIT-LICENSE
Octocat-spinner-32 README.rdoc
Octocat-spinner-32 Rakefile
Octocat-spinner-32 about.yml
Octocat-spinner-32 cells.gemspec


View Components for Rails.


Say you're writing a Rails online shop - the shopping cart is reappearing again and again in every view. You're thinking about a clean solution for that part. A mixture of controller code, before-filters, partials and helpers?

No. That sucks. Take Cells.

Cells are View Components for Rails. They look and feel like controllers. They don't have no DoubleRenderError. They are callable everywhere in your controllers or views. They are cacheable, testable, fast and wonderful. They bring back OOP to your view and improve your software design.


It's a gem!

Rails 3:

gem install cells

Rails 2.3:

gem install cells --version 3.3.4


Creating a cell is nothing more than

$ rails generate cell ShoppingCart display
  create  app/cells/
  create  app/cells/shopping_cart
  create  app/cells/shopping_cart_cell.rb
  create  app/cells/shopping_cart/display.html.erb
  create  test/cells/shopping_cart_test.rb

That looks very familiar.

Render the cell

Now, render your cart. Why not put it in layouts/application.html.erb for now?

<div id="header">
  <%= render_cell :shopping_cart, :display, :user => @current_user %>

Feels like rendering a controller action. As additional encapsulation we pass the current user from outside. Call it knowledge hiding.


Time to improve our cell code. Let's start with app/cells/shopping_cart_cell.rb:

class ShoppingCartCell < Cell::Rails 
  def display 
    @items = @opts[:user].items_in_cart

    render  # renders display.html.erb

Is that a controller? Hell, yeah. We even got a render method as we know it from the good ol' ActionController.


Since a plain call to render will start rendering app/cells/shopping_cart/display.html.erb we should put some meaningful markup there.

<div id="cart">
  You have <%= @items.size %> items in your shopping cart. 

Haml? Builder?

Yes, Cells support all template types that are supported by Rails itself. Remember- it's a controller!


Yes, Cells have helpers just like controllers. If you need some specific helper, do

class ShoppingCartCell < Cell::Rails 
  helper MyExtraHelper

and it will be around in your cart views.


Cells do strict view caching. No cluttered fragment caching. Add

class ShoppingCartCell < Cell::Rails 
  cache :display, :expires_in => 10.minutes

and your cart will be re-rendered after 10 minutes.

There are multiple advanced options for expiring your view caches, including an expiration lambda.

class ShoppingCartCell < Cell::Rails 
  cache :display do |cell|


Another big advantage compared to monolithic controller/helper/partial piles is the ability to test your cells isolated.

So what if you wanna test the cart cell? Use the generated test/cells/shopping_cart_test.rb test.

class ShoppingCartTest < ActionController::TestCase
  include Cells::AssertionsHelper

  test "display" do
    html = render_cell(:shopping_cart, :diplay, :user => @user_fixture)
    assert_selekt html, "#cart", "You have 3 items in your shopping cart."

That's easy, clean and strongly improves your component-driven software quality. How'd you do that with partials?

More features

Cells can do more.

View Inheritance

Inherit view files dynamically from parent cells.

Cell Nesting

Have complex cell hierarchies as you can call render_cell within cells, too.

Go for it, you'll love it!


Copyright © 2007-2010, Nick Sutterer

Copyright © 2007-2008, Solide ICT by Peter Bex and Bob Leers

Released under the MIT License.

Something went wrong with that request. Please try again.