Recently I have a plan to build very small personal web applications using Ruby. My choice is using Sinatra. Why? Using Ruby on Rails is too big for my projects. Using Padrino is still too big for my projects.

So I decide to create Melodiest as generator for each my projects. The goal is to generate Sinatra application with minimalist code and configuration.

Installation

gem install melodiest

generate app in current directory without database
melodiest -n my_app

generate app in target directory without database
melodiest -n my_app -t target/dir

generate app in current directory with database. -d option will generate app with Sequel ORM and PostgreSQL adapter.
melodiest -n my_app -d

Default Configuration

Default configuration for Melodiest version 0.3.0:
  • Sinatra::Reloader (in development environment only)
  • Thin as web server
  • Rack::Session::EncryptedCookie
  • Rack::Csrf
  • Sequel ORM (with database only)
  • sequel_pg as PostgreSQL adapter (with database only)

Example Usage

We will create todo application named todo_melodiest. This example assume that PostgreSQL is already running.
  1. Create database with this command:
    createdb todo_melodiest
  2. Generate project with this command:
    melodiest -n todo_melodiest -d
  3. Move to todo_melodiest directory, and run bundle install:
    cd todo_melodiest
    bundle install
  4. create config/database.yml and write your database configuration, example:
    development:
    adapter: postgres
    host: localhost
    database: todo_melodiest
    user: my_example_user
    password: my_example_password
  5. create file db/migrations/001_create_tasks.rb and put the following code:
    Sequel.migration do
    up do
    create_table :tasks do
    primary_key :id
    String :name, :null=>false
    end
    end

    down do
    drop_table :tasks
    end
    end
  6. Migrate the migration to latest version:
    rake db:migrate

    If you want to migrate to specific version:
    rake db:migrate[001]
  7. create file app/models/Task.rb and put the following code:
    class Task < Sequel::Model
    end
  8. create file app/routes/tasks.rb and put the following code:
    class TodoMelodiest
    get '/' do
    "hello world!"
    end

    get '/tasks' do
    @tasks = Task.all
    erb :'tasks/index'
    end

    post '/tasks' do
    @task = Task.new
    @task.name = params[:name]
    @task.save

    redirect '/tasks'
    end

    get '/tasks/edit/:id' do
    @task = Task[params[:id]]

    erb :'tasks/edit'
    end

    put '/tasks' do
    @task = Task[params[:id]]
    @task.name = params[:name]
    @task.save

    redirect '/tasks'
    end

    delete '/tasks' do
    @task = Task[params[:id]]
    @task.destroy

    redirect '/tasks'
    end
    end
  9. create file app/views/tasks/index.erb and put the following code:
    <h1>Tasks</h1>
    <ul>
    <% @tasks.each do |task| %>
    <li>
    <%= task.name %> | <a href="/tasks/edit/<%= task.id %>">Edit</a>
    <form action="/tasks" method="post">
    <%= Rack::Csrf.tag(env) %>
    <input name="_method" type="hidden" value="delete" />
    <input name="id" type="hidden" value=<%= task.id %> />
    <button>Delete</button>
    </form>
    </li>
    <% end %>
    </ul>

    <form action="/tasks" method="post">
    <%= Rack::Csrf.tag(env) %>
    <input type="text" name="name" />
    <button>Submit</button>
    </form>
  10. create file app/views/tasks/edit.erb and put the following code:
    <h1>Edit Task <%= @task.name %></h1>
    <form action="/tasks" method="post">
    <%= Rack::Csrf.tag(env) %>
    <input name="_method" type="hidden" value="put" />
    <input name="id" type="hidden" value=<%= @task.id %> />
    Name: <input type="text" name="name" />
    <button>Submit</button>
    </form>
  11. Run the server:
    bundle exec thin start
  12. open url localhost:3000/tasks
Github repo for this example: https://github.com/kuntoaji/todo_melodiest