Latest Items
Has N
  • pages
Latest Items
Belongs To
  • author
Has N
  • menus
Is Tree
This demo backend is built using Saint.
Saint is a tool that helps to build backends for web sites.
Basically, it takes a DataMapper model and builds a CRUD interface for it.

You need one line of code to get started: saint.model ModelName

Below is a quick introductory tutorial. This tutorial assume you are familiar with general Ruby syntax and DataMapper ORM.

Tutorial Goals

Getting Started

In fact, this section could be named "Getting Finished", cause all you need to do is to create controllers and declare models.

Everything else is done by Saint!

So, lets create controllers and define models.

Saint itself is just a module that integrates into controllers and extend them.

For now, Saint supports only Presto Framework controllers.

A generic Presto controller looks like this:

class SomeController
    include Presto::Api
    http.map '/some/url'
end

Worth to note that any class including Saint::Api will also include Presto::Api, so we can setup Saint right after including its Api.

Regard models declaration - it is as easy as calling saint.model inside created controller.

That's all about theory. Lights, Camera!

Creating interface for Country model

class Country
    include Saint::Api
    http.map :country
    saint.model Model::Country
end

Creating interface for Author model

class Author
    include Saint::Api
    http.map :author
    saint.model Model::Author
end

Creating interface for Menu model

class Menu
    include Saint::Api
    http.map :menu
    saint.model Model::Menu
end

Creating interface for Page model

class Page
    include Saint::Api
    http.map :page
    saint.model(Model::Page) { filters_ignored :meta_title, :content }
    saint.column :content, :rte
    saint.subset :active, Active: true, Suspended: false
end

Building the File Manager

class FileManager
    include Saint::Api
    http.map :file_manager
    saint.menu { label 'File Manager'; position -1000 }
    saint.fm do
        root File.expand_path '../var/tmp/public', __FILE__
        root File.expand_path '../var/tmp/templates', __FILE__
    end
end

That's all! Really

- That's all the code you need to build an fully-fledged admin interface.
- It will manage all the columns in given models.
- It will manage all the associations in given models.
- It will have filters for all columns.
- All this in about 40 lines of code.

Click here to see this code in action. For more details on building interfaces, click here.

Putting code together

module Ctrl

  class Country
    include Saint::Api
    http.map :country
    saint.model Model::Country
  end

  class Author
    include Saint::Api
    http.map :author
    saint.model Model::Author
  end

  class Menu
    include Saint::Api
    http.map :menu
    saint.model Model::Menu
  end

  class Page
    include Saint::Api
    http.map :page
    saint.model(Model::Page) { filters_ignored :meta_title, :content }
    saint.column :content, :rte
    saint.subset :active, Active: true, Suspended: false
  end

  class FileManager
    include Saint::Api
    http.map :file_manager
    saint.menu { label 'File Manager'; position -1000 }
    saint.fm do
      root File.expand_path '../var/tmp/public', __FILE__
      root File.expand_path '../var/tmp/templates', __FILE__
    end
  end
end

For sure you noted this code wont work without ORM models.

That's true. As true is the fact that defining ORM models is not a job of Saint.
Your site will use models anyway(if it communicating to a database through an ORM).

Below are the models used for this Demo Site.

ORM Models

module Model
  class Country
    include DataMapper::Resource
    property :id, Serial
    property :name, String
  end

  class Author
    include DataMapper::Resource
    property :id, Serial
    property :name, String
  end

  class Menu
    include DataMapper::Resource
    property :id, Serial
    property :name, String
    property :body, Text
  end

  class MenuPage
    include DataMapper::Resource
    property :id, Serial
  end

  class Page
    include DataMapper::Resource
    property :id, Serial
    property :name, String
    property :meta_title, String
    property :content, Text
    property :active, Boolean
    property :created_at, Date
  end
end

ORM Associations

module Model
  class Author
    has n, :pages
    belongs_to :country, required: false
  end

  class Country
    has n, :authors
  end

  class Menu
    has n, :related_pages, model: MenuPage, child_key: :menu_id
    has n, :pages, model: Page, through: :related_pages
  end

  class MenuPage
    belongs_to :menu, model: Menu, child_key: :menu_id
    belongs_to :page, model: Page, child_key: :page_id
  end

  class Page
    is :tree
    belongs_to :author, required: false
    has n, :related_menus, model: MenuPage, child_key: :page_id
    has n, :menus, model: Menu, through: :related_menus
  end
end

Deploy this tutorial

All the code above is assembled in an single file - app.rb

To visualize assembled code, please access https://github.com/slivu/demo.saintrb.org/blob/master/app.rb

To run this app you need to download it from GitHub.com

If you have git installed, simply do:

git clone git://github.com/slivu/demo.saintrb.org.git

Otherwise, download app as a zip file from https://github.com/slivu/demo.saintrb.org/zipball/master and unzip it.

Whatever method you choosed, now use your terminal to enter demo.saintrb.org/ folder:

cd ./demo.saintrb.org/

If you have no bundler installed, install it:

sudo gem install bundler

Now install all gems required by app:

bundle install

Next, open app.rb with your favourite editor and edit app_config Hash.

Then close your editor and run the rake task that will create db schema:

rake db:migrate

and another task that will populate db with arbitrary data:

rake db:populate

now, to start app, simply run the app.rb file:

ruby app.rb

Deploy Saint

Saint can be used as a standalone app or it can be integrated into an existing website.

Either way, you just need to mount a module into a Presto app.

In this tutorial, we built Saint under Ctrl module, so mounting Ctrl under desired url.

Creating app:

app = Presto::App.new

Mounting Saint slice:

app.mount Ctrl, '/admin'

Start app using WEBrick on its default port:

app.run

or, start app using Thin on 7890 port

app.run server: :Thin, Port: 7890

Now Saint should run at http://localhost/admin:[PORT_NUMBER]

comments powered by Disqus