Skip to content

From Cells 3 to Cells 4 Upgrading Guide

David Southard edited this page Jun 10, 2015 · 7 revisions

3.x to 4.0

Template engine

You have to pick and install one (or multiple) template engines for your application. This will usually end in adding gem "cells-haml" to your Gemfile. Learn more.

Architecture

The old dialect Cell::Base and Cell::Rails got superceded by Cell::ViewModel. So, every cell should start like

class SongCell < Cell::ViewModel
  def show
    render
  end

This also changes a few semantical things in your cell.

render_cell helper

The helper #render_cell got replaced with #cell.

cell(:song, Song.find(1), genre: "Heavy Metal")

The first argument is a model to present, then a hash with additional parameters can be passed. It will return the cell instance. In a view, this will automatically call #to_s, which internally invokes the #show method.

Multiple public methods

Often, people use one cell class with multiple public methods to render different views. If you don't want to render the #show method use #call.

cell(:song, Song.find(1)).(:details)

Of course, this assumes you have a method #details.

class SongCell < Cell::ViewModel
  def details
    render
  end

Options

Passing options used to work like this.

render_cell(:comment, @comment, layout: :fancy)

This still works with #cell. However, those options are now available via #options.

def show
  render layout: options[:layout]
end

You can still pass options to the method directly, this works as follows.

cell(:comment, @comment).call(:show, layout: :fancy)

Your action method will then need to process those options.

def show(layout=default)
  render layout: layout
end

Because the second parameter in the cell helper is to determine the model being used, you still need to instantiate your instance variables using the options hash, similar to how args was handled in v3.0.

cell(:comment, @comment, comment: comment).call(:show)

In the cell method instantiate your variables from the options passed

def show
  @comment = options[:comment]
  render
end

Now you can call your object as an instance variable in the cell view.

= @comment.content

Builders

Builders are no longer executed in the controller context. They also now receive the exact args list that was passed into #cell.

If you need controller data for your builders, push that into the options hash.

class SongCell < Cell::ViewModel
  build do |model, options|
    HitCell if model.is_a? Hit
  end

Asset Pipeline

The old configuration in application.rb looks like this.

config.cells.with_assets = ["comment"] # references Comment::Cell.

This becomes a fully qualified underscore constant name.

config.cells.with_assets = ["comment/cell"] # references Comment::Cell.

Also, assets like comment.js do no longer have their own directory but all sit in the cell's views directory.