AjaxScaffold

A RubyOnRails Generator for Firefox 1+, IE 6+ & Safari 2+

Developed by Richard White, et al.

www.ajaxscaffold.com

Eric Wagoner

A Presentation for AtlRUG, June 6, 2006

AjaxScaffold Features

Getting Started

(Full text of migrations file appears on printed page and in source.)

File: db/migrate/001_bootstrap_application.rb
class BootstrapApplication < ActiveRecord::Migration
  def self.up
    create_table :events do |t|
      t.column :name,        :string,  :null => false
      t.column :date,        :date,    :null => false
      t.column :period_id,   :integer, :null => false
      t.column :location_id, :integer, :null => false
    end

    create_table :people do |t|
      t.column :name,    :string,  :null => false
      t.column :title,   :string
      t.column :company, :string,  :null => false
      t.column :phone,   :string,  :null => false
      t.column :email,   :string,  :null => false
    end

    create_table :periods do |t|
      t.column :name,  :string, :null => false
      t.column :times, :string, :null => false
    end

    create_table :locations do |t|
      t.column :name,    :string, :null => false
      t.column :address, :string, :null => false
    end

    Period.create(:name => 'Morning', :times => '9:00am - 12 noon')
    Period.create(:name => 'Afternoon', :times => '1:00pm - 5:00pm')
    Period.create(:name => 'All Day', :times => '9:00am - 5:00pm')
    Period.create(:name => 'Two Days', :times => '9:00am - 5:00pm both days')

    Location.create(:name => 'Partner Office', :address => '825 S. Milledge Ave.')
    Location.create(:name => 'Hilton Garden Inn', :address => 'Downtown Athens')
    Location.create(:name => 'Holiday Inn', :address => 'Broad Street, Downtown Athens')

  end

  def self.down
    drop_table :events
    drop_table :people
    drop_table :periods
    drop_table :locations
  end
end

Let's Take a Look!

All CRUD Present and Accounted For

Sorting and pagination, too!

What more do you need?

Repeat As Needed

It Handles Validations

app/models/period.rb
validates_presence_of :name, :times

app/models/location.rb
validates_presence_of :name, :address

It Handles belongs_to

app/models/event.rb
belongs_to :location
belongs_to :period

@scaffold_columns = [
    AjaxScaffold::ScaffoldColumn.new(self, { :name => "name", :label => "Training Session" }),
    AjaxScaffold::ScaffoldColumn.new(self, { :name => "date", :label => "Starting Date" }),
    AjaxScaffold::ScaffoldColumn.new(self, { :name => "period", :label => "Session Length", :eval => "event.period.name + ' -- ' + event.period.times", :sort_sql => "period.name" }),
    AjaxScaffold::ScaffoldColumn.new(self, { :name => "location", :label => "Training Location", :eval => "event.location.name", :sort_sql => "location.name" }),
]

(Next Slide)

It Handles belongs_to (has_many)

app/models/period.rb
has_many :events

app/models/location.rb
has_many :events

(Next Slide)

It Handles belongs_to (form selects)

app/views/events/_form.rhtml
<div class="form-element">
  <label for="event_length">Length</label>
  <%= select 'event', 'period_id' , Period.find_all.collect {|p| [ p.name, p.id ] } %>
</div>

<div class="form-element">
  <label for="event_location">Location</label>
  <%= select 'event', 'location_id' , Location.find_all.collect {|l| [ l.name, l.id ] } %>
</div>

You Can Use in_place_editor

app/controllers/periods_controller.rb
in_place_edit_for :period, :times

app/views/periods/_period.rhtml

<% @period = period %>
Make this the first line!

<% if scaffold_column.name == "times" %>
  <%= in_place_editor_field :period, :times %>
<% else %>
  <%= format_column(column_value) %>
<% end %>

Create an Admin Panel

ruby script/generate ajax_scaffold People Admin
(don't overwrite your changes!)

app/views/admin/list.rhtml
Copy single line to include all your models. Change controller names.

<%= render_component :controller => '/events', :action => 'component', :params => params %>
<%= render_component :controller => '/periods', :action => 'component', :params => params %>
<%= render_component :controller => '/locations', :action => 'component', :params => params %>
<%= render_component :controller => '/people', :action => 'component', :params => params %>

Other Goodies

It's Supported!

FarmNotebook.com Examples

I've used this scaffolding extensively at FarmNotebook.com. Let's take a look...