Check out my consultancy offering at RailsReviews.com!

TemplateReflex

Compose a UI using page morphs

How?

  • UI components (“templates”) are inserted/removed using two reflex actions, and are identified by uuids
  • The session is used to persist/manage them

Caveat

Note that in a real-world app, you’d probably want to use model partials and empty model instances to construct your UI (the Template class acts as a stand-in for both model and partial)

Variations

Use kredis as ephemeral persistence store

app/reflexes/template_reflex.rb

class TemplateReflex < ApplicationReflex
  def insert
    current_user.templates << Cell.new(uuid: SecureRandom.urlsafe_base64)
  end

  def remove(uuid = element.dataset.uuid)
    current_user.templates.delete_if { |template| template.uuid == element.dataset.uuid }
  end
end

app/controllers/grid_controller.rb

class GridController < ApplicationController
  def index
    @cells = Cell.all
  end
end

app/models/cell.rb

class Cell < ApplicationRecord
  attribute :uuid, :string
end

app/models/user.rb

class User < ApplicationRecord
  attr_accessor :templates
  
  def initialize
    super
    @templates = []
  end
end

app/views/cells/index.html.erb

<div class="grid">
  <%= render @cells %>
  <%= render current_user.templates %>
  <%= tag.a "Add Cell", class: "btn btn-primary", data: { reflex: "click->Template#insert" } %>
</div>

app/views/cells/_cell.html.erb

<div class="cell">
  <button type="button" class="btn-close" aria-label="Close" data-reflex="click->Template#remove" data-uuid=#{cell.uuid}></button>
</div>