window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster already exists') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() A Simple Ruby Application from Scratch with Active Record - The Codest
The Codest
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Industries
    • Fintech & Banking
    • E-commerce
    • Adtech
    • Healthtech
    • Manufacturing
    • Logistics
    • Automotive
    • IOT
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
Back arrow GO BACK
2021-07-07
Software Development

A Simple Ruby Application from Scratch with Active Record

The Codest

Damian Watroba

Software Engineer

MVC is a design pattern that divides the responsibilities of an application to make it easier to move about. Rails follows this design pattern by convention.

I like working with Rails because I can easily and quickly create an application that works and show it to the world or just my friends. However, there are types of applications that do not need such a large framework as Rails and all its functionalities.

It may happen that our application needs only M (Model) out of the whole MVC pattern Model-Controller. Is it worth starting a project in Rails if we know that the V-C (View-Controller) part will not be needed?

It’s good to know that Active Record , Active Model, Action Pack and Action View, which are responsible for MVC, can be used independently outside Rails. This allows us to create a simple Ruby application that has a database connection and develop it without the unnecessary code and libraries that we would get in a package by running the rails new command.

I have described step by step how to achieve this and you can find the whole code on GitHub. The link is at the bottom of this article. 

Structure

To start our project, we don’t need much. Let’s start by creating a Gemfile where we add the gems we need to work on the application, along with the version of Ruby we will be using.

 cat Gemfile

# frozen_string_literal: true

source 'https://rubygems.org'

ruby '2.7.2'

An optional README.md file is to describe how our application works and how to continue working on it, both for ourselves and other developers who will want to develop the project with us in the future.

cat README.md

# Application

TO DO: Delete this and the text above, and describe your app

app directory with application.rb file, which will be responsible for configuration and loading libraries and files we will be adding in our application. Remember to run bundle install to generate the Gemfile.lock. The structure of our application at this stage should look like this:

 tree
 .
 ├── Gemfile
 ├── Gemfile.lock
 ├── README.md
 └── app
     └── application.rb

Database

With such a structure prepared, we can consider which database engine to choose and configure. For this article, I chose PostgresQL, with which I have the most experience. It can also be MySQL or SQlite3, or any other engine working with Active Record. When choosing technology, it is good to be guided by the purpose of the application, what it will be used for and what its purpose will be. 

For a quick and simple database configuration, I used docker and docker-compose. I don’t want to elaborate on the configuration of these tools, their pros and cons, but if you’ve never used docker before then I’d refer you to the official documentation for Docker and Docker Compose for more information.

# docker-compose.yml

version: '3.7'
services:
  postgresql:
    image: postgres:12.0-alpine
    ports:
- 5432:5432
    environment:
- PGDATA=/postgresql
- POSTGRESPASSWORD=postgres
- POSTGRESUSER=postgres
    volumes:
- db-volume:/postgresql
volumes:
  db-volume:

We will also need to add to our Gemfile

 gem 'pg'

and to our application.rb file

# app/application.rb

require 'pg'

module Application

  class Error < StandardError; end

# Your code goes here...

end

Standalone Migrations, Rake

The next step in configuring our application is to add the standalone_migrations and rake gems, which will allow us to manage our migrations just like in Rails and gain access to rake db: commands. 

  1. Update Gemfile with the necessary gems, and do a bundle install
# gem used in non-rails and non-ruby applications

gem 'standalone_migrations'

# standalone_migrations need rake to be able to create migrations and run them, as in Rails

gem 'rake'

# Gem needed to load environment variables

gem 'dotenv'
  1. Let’s add a Rakefile to our project in the root directory, where we will load dotenv and standalone_migrations that we added earlier 
# frozen_string_literal: true

require 'dotenv'

Dotenv.load

require 'standalone_migrations'

StandaloneMigrations::Tasks.load_tasks

With the Rakefile configured this way, we can check if our rake is working by using the rake -T command, which should return a list of available commands in our application.

ruby app
  1. Before rake db:create, we still need to have a configuration file in our project to connect to the Postgres instance. To do this, we need to create a db directory along with a config.yml file that should look like the one below:
# db/config.yml

default: &default

  adapter: postgresql

  encoding: unicode

  pool: <%= ENV.fetch('MAX_THREADS') { 5 } %>

  database: <%= ENV.fetch('DATABASE_NAME') %>

  username: <%= ENV.fetch('DATABASE_USER') %>

  password: <%= ENV.fetch('DATABASE_PASSWORD') %>

  host: <%= ENV.fetch('DATABASE_HOST') %>

  port: <%= ENV.fetch('DATABASE_PORT') %>

development:

  <<: *default

test:

  <<: *default

staging:

  <<: *default

production:

  <<: *default

As you can see, I used environment variables to configure the connection to our Postgres, where we will keep sensitive data that should not be in the repository. For this I used the previously added gem dotenv, which was also added in the Rakefile along with standalone_migrations. If we are using Git to manage version control of our application, let’s remember to add a .gitignore file where we will disable the possibility of tracking the .env file from our project.

 # .gitignore
.env*
!.env.example

and add an.env file containing the correctly configured ENV

# .env

DATABASE_NAME="development"

DATABASE_USER="postgres"

DATABASE_PASSWORD="postgres"

DATABASE_HOST="localhost"

DATABASE_PORT="5432"
  1. At this stage, we should be able to run the rake db:create command which will create the database

    Ruby web application

  2. Let’s try adding a new migration via rake db:new_migration name=, where we create a posts table with a :title column

    Rails web application

# frozen_string_literal: true

class CreatePosts < ActiveRecord::Migration[6.0]

  def change

    create_table :posts do |t|

      t.string :title

    end

  end

end
Ruby on Rails web application

You should notice that the db/migrate directory was automatically added and schema.rb was created after successful migration. Currently, our project structure looks as follows:

 tree
.
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── .gitignore
├── .env.example
├── app
│   └── application.rb
├── db
│   ├── config.yml
│   ├── migrate
│   │   └── 20210504135128_create_posts.rb
│   └── schema.rb
└── docker-compose.yml

Active Record

The last but not least, another step in creating our application is to add activerecord and its configuration. For this, we will need to update our Gemfile with 3 more gems:

gem 'activerecord'
gem 'erb'
gem 'yaml'

Why we add erb and ymal is explained below in the comments. The entire active_record configuration will be in the app/application.rb file.

Let’s go through what happens here, one by one:

# frozen_string_literal: true

# If we want to be able to run the application in different environments,
# e.g. test or production, it is good to set the ENVIRONMENT value
# at the beginning, which is taken from the environment variable
# or `development` by default.

ENV['ENVIRONMENT'] ||= 'development'

# To use the added gems, we need to load them using the Kernel#require method,
# which loads the file or library passed as a parameter

require 'pg'
require 'active_record'
require 'dotenv'
require 'yaml'
require 'erb'

# By default Dotenv.load for loading environment variables reaches out
# to the `.env` file, so if we want to use other environments it is worth
# extending this to the method below, which will first for a set development
# environment look for a file ending in `.env.development.local`,
# then `.env.development` and finally `.env`.

Dotenv.load(".env.#{ENV.fetch('ENVIRONMENT')}.local", ".env.#{ENV.fetch('ENVIRONMENT')}", '.env')

# Method needed for loading database settings
def db_configuration
  # The method below returns the path to the file with our configuration
  db_configuration_file_path = File.join(File.expand_path('..', __dir__), 'db', 'config.yml')

  # Having the path to the file, we can read its values. Because the config.yml
  # file contains environment variables and, as you may have noticed,
  # the erb <%= %> syntax, we also need to use the erb gem. Without this,
  # the values of the variables will not be read correctly and activerecord
  # will not be able to connect to postgres.The following method will return
  # the configuration as a string

  db_configuration_result = ERB.new(File.read(db_configuration_file_path)).result

  # Using the previously added `yaml` gem, we can safely load our configuration

  YAML.safe_load(db_configuration_result, aliases: true)
end

# Finally, we need to create a connection between activerecord and postgres
# using the `establish_connection` method
ActiveRecord::Base.establish_connection(db_configuration[ENV['ENVIRONMENT']])

module Application
  class Error < StandardError; end
  # Your code goes here...
end

We already have the configurations, so we can add the Post model in our ruby app. 

`├── app`

`│   └── models`

`│       └── post.rb`
app/models/post.rb
# frozen_string_literal: true

class Post < ActiveRecord::Base;end

and remember to load the file in application.rb

require 'app/models/post'

Also, remember to add require 'app/runner' to app/application.rb

If we want to add new files in our application, services, more models, we need to load them in application.rb.

SUMMARY

Currently, our ruby application is ready to continue. We have configured:

  • database connection,
  • Active Record,
  • Standalone migrations with rake

As you can see, it is not always necessary to use rails new. This way we avoid unnecessary code in our application that is not used. We have more control over the development of our application. We can add more libraries and business logic over time. We can use such configured application to create a crawler or scraper, connect to external API from which we will retrieve information and store in our own database or load files and extract interesting information from them. I wish you good luck with the further development of your own applications!

BONUS

Our application also needs to be started somehow. We can do it in several ways, for example from the terminal. We can create an exe/app file that will load our application logic from the 'app/application' file and run our application through the Runner service added in the app directory.

#!/usr/bin/env ruby
# frozen_string_literal: true

require 'bundler/setup'

$LOAD_PATH.unshift File.expand_path('..', __dir__)
require 'app/application'

Runner.start
# frozen_string_literal: true

class Runner
  def self.start
    puts 'Start'
  end
end
ruby app development

Also remember to add require 'app/runner' to app/application.rb

Code can be found on GitHub:

– https://github.com/dwatek/simplerubyapp

Read More

GraphQL Ruby. What about performance?

Rails and Other Means of Transport

Rails Development with TMUX, Vim, Fzf + Ripgrep

Related articles

Software Development

Build Future-Proof Web Apps: Insights from The Codest’s Expert Team

Discover how The Codest excels in creating scalable, interactive web applications with cutting-edge technologies, delivering seamless user experiences across all platforms. Learn how our expertise drives digital transformation and business...

THECODEST
Software Development

Top 10 Latvia-Based Software Development Companies

Learn about Latvia's top software development companies and their innovative solutions in our latest article. Discover how these tech leaders can help elevate your business.

thecodest
Enterprise & Scaleups Solutions

Java Software Development Essentials: A Guide to Outsourcing Successfully

Explore this essential guide on successfully outsourcing Java software development to enhance efficiency, access expertise, and drive project success with The Codest.

thecodest
Software Development

The Ultimate Guide to Outsourcing in Poland

The surge in outsourcing in Poland is driven by economic, educational, and technological advancements, fostering IT growth and a business-friendly climate.

TheCodest
Enterprise & Scaleups Solutions

The Complete Guide to IT Audit Tools and Techniques

IT audits ensure secure, efficient, and compliant systems. Learn more about their importance by reading the full article.

The Codest
Jakub Jakubowicz CTO & Co-Founder

Subscribe to our knowledge base and stay up to date on the expertise from the IT sector.

    About us

    The Codest – International software development company with tech hubs in Poland.

    United Kingdom - Headquarters

    • Office 303B, 182-184 High Street North E6 2JA
      London, England

    Poland - Local Tech Hubs

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warsaw, Poland

      The Codest

    • Home
    • About us
    • Services
    • Case Studies
    • Know How
    • Careers
    • Dictionary

      Services

    • It Advisory
    • Software Development
    • Backend Development
    • Frontend Development
    • Staff Augmentation
    • Backend Developers
    • Cloud Engineers
    • Data Engineers
    • Other
    • QA Engineers

      Resources

    • Facts and Myths about Cooperating with External Software Development Partner
    • From the USA to Europe: Why do American startups decide to relocate to Europe
    • Tech Offshore Development Hubs Comparison: Tech Offshore Europe (Poland), ASEAN (Philippines), Eurasia (Turkey)
    • What are the top CTOs and CIOs Challenges?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. All rights reserved.

    en_USEnglish
    de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek en_USEnglish