Start tinkering

Single-File Ruby Templates

Experimenting with Ruby, a new Ruby gem or full-blown Rails?
Start with a no-fuss single-file Ruby script template.

  • Most basic template with just bundler/inline.

    require "bundler/inline"
    gemfile do
      source ""
      # add gems you need here
    puts "Start tinkering!"
  • Basic template with some auto-run magic by keepgoing.

    require "bundler/inline"
    gemfile do
      source ""
      gem "keepgoing" # auto-runs script on changes
      # add gems you need here
    puts "Keep tinkering!"
  • Template coming with active_support and auto-run by keepgoing.

    require "bundler/inline"
    gemfile do
      source ""
      gem "keepgoing" # auto-runs script on changes
      gem "activesupport"
      # add gems you need here
    require "active_support/all"
    puts "Ain't nobody got time for this".truncate(25)
  • Connect to a PostgreSQL database, query and create records using ActiveRecord.

    require "bundler/inline"
    gemfile do
      source ""
      gem "activerecord"
      gem "pg"
    require "active_record"
    ActiveRecord::Base.establish_connection(adapter: "postgresql", database: "ruby_starters_development")
    ActiveRecord::Base.logger =
    # Get list of tables in the database
    tables =
      .execute("select * from pg_catalog.pg_tables where schemaname = 'public'")
    # Define ActiveRecord Model classes for all tables
    puts "\n\nAvailable Models (and tables):\n\n"
    tables.each do |table, model: table.classify|
      puts "#{model} (#{table})"
    # When connecting to a Rails generated db, chances are there is a schema_migrations table:
    puts SchemaMigration.last.inspect
    # Suppose there is a users table we can query that:
    puts User.where(first_name: "Wolfgang").count
    # WE can create records, too!
    # But mind you are bound by db constraints only,
    # there are no validations unless you defined them here:
    # User.create!(email: "", first_name: "Wolfgang")
  • HTTP requests to with Faraday incl. some middleware.

    require "bundler/inline"
    gemfile do
      source ""
      gem "keepgoing" # auto-runs script on changes
      gem "faraday", "~> 2.3"
      gem "faraday-retry", "~> 1.0"
    require "faraday"
    require "faraday/retry"
    # configure Faraday incl. some middleware
    retry_options = {
      max: 2,
      interval: 0.5,
      retry_statuses: [500],
      retry_block: -> (env, _options, _retries, _exc) { puts "\n\ngot #{env.status} 😱 will retry\n\n" }
    connection ="") do |f|
      f.request :json # encode req bodies as JSON and automatically set the Content-Type header
      f.request :retry, retry_options
      f.response :json # decode response bodies as JSON
      f.response :logger
    # POST request
    response ="/post") do |req|
      req.params["limit"] = 100
      req.body = {query: "chunky bacon"}
    # GET some json
    response = connection.get("/json")
    puts "\n", response.body.dig("slideshow", "title"), "\n"
    # test-drive retries
    response = connection.get("/unstable")
    puts "\n", response.status
  • Full-blown Rails app with SQLite database (in-memory). No setup required.

    require "bundler/inline"
    gemfile do
      source ""
      gem "rails"
      gem "sqlite3"
      gem "puma"
      # add gems you need here
    # using SQLite in memory; mind that's only working with max. 1 connection
    require "active_record"
    require "action_controller/railtie"
    ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:", pool: 1)
    ActiveRecord::Base.logger =
    ActiveRecord::Schema.define do
      create_table :notes do |t|
        t.string :title
        t.text :body
    class Note < ActiveRecord::Base
      validates :title, presence: true
    Note.create(title: "Hello World!", body: "Greetings from Single-File Rails 👋")
    Note.create(title: "Reminder", body: "You need to stop and restart for changes to take effect")
    Note.create(title: "Missing Feature", body: %(Sadly the <a class="text-blue-400 hover:text-blue-600" href="">keepgoing gem</a> does not play nicely with Rails yet.))
    Note.create(title: "Still great", body: "This is still a great way to quickly try something out 🎉<br>Even with full-blown Rails 🛤")
    # Put back the db connection, because there's only 1, remember
    class InlineApp < Rails::Application
      secrets.secret_token    = "secret_token"
      secrets.secret_key_base = "secret_key_base"
      config.logger =$stdout)
      Rails.logger = config.logger
      routes.draw do
        resources :notes, only: %i[index create]
        root to: redirect('/notes')
    class NotesController < ActionController::Base
      include Rails.application.routes.url_helpers
      def index
        @notes = Note.all
        render inline: notes_html
      def create
        Note.create(title: "New Note #{Note.count + 1}", body: "This is your new note")
        redirect_to notes_path
      def notes_html
          <!DOCTYPE html>
          <title>Single-File Rails</title>
          <script src=""></script>
          <body class="bg-zinc-50 flex gap-5 p-5 flex-wrap">
            <h1 class="font-bold text-xl text-red-500 w-full">Single-File Rails Notes</h1>
            <% @notes.each do |note| %>
              <div class="bg-white rounded shadow p-5 w-full sm:max-w-sm">
                <h2 class="font-bold text-emerald-400 mb-1"><%= note.title %></h1>
                <p><%= note.body.html_safe %></p>
            <% end %>
            <%= form_with url: notes_path, class: "w-full" do |form| %>
              <%= form.submit "Create New Note", class: "rounded bg-emerald-300 px-3 py-1 border border-emerald-500 hover:bg-emerald-400 text-emerald-900" %>
            <% end %>
    require "puma"
    require "rails/command"
    require "rails/commands/server/server_command"
    options = {
      app: InlineApp,
      Port: 3000,
      min_threads: 1,
      max_threads: 1