There’s a couple of very helpful guides to creating a basic Ruby on Rails app:

There’s a text based tutorial: https://guides.rubyonrails.org/getting_started.html#introduction

I followed this video tutorial (quite fast so needed to pause at some points as I was coding alongside watching): https://youtube.com/playlist?list=PLHFP2OPUpCeZcPutT9yn4-e0bMmrn5Gd1&si=Ryz3VkAiqKyc2ygH

Here are a few useful hints and differences if you already have some experience with web apps in other languages:

1. Installing Rails

Installing Rails and managing the versions seems a little clunky, there’s basically 2 options:

a) Install rails system wide, but then every Rails project you create uses the same version of Rails:

gem install rails

b) Setup a new Ruby project folder, and add rails to the gemfile, and then create Rails app from there, which will be inside another folder. This inner folder is what will be added to version control, not the one that hosts the Rails installation. I went for this method.

mkdir rails_projects && cd rails_projects# folder setup
rv ruby pin 3.4.7 # creates .ruby-version
bundle init # creates Gemfile for dependencies (like pyproject.toml)
bundle config set --local path vendor/bundle # tell bundle where to install gems
##Gemfile##
source "https://rubygems.org"
gem "rails", "~> 8.1"
bundle install
bundle exec rails new my_new_rails_app

So the folder structure will be like this:

rails_projects # holding project for rails installation
├── .bundle 
│    └── config 
├── .ruby-version
├── Gemfile
├── Gemfile.lock
├── my_new_rails_app # your rails app for version control
│   ├── app
│   ├── bin
│   ├── config
│   ├── config.ru
│   ├── db
│   ├── Dockerfile
│   ├── Gemfile
│   ├── Gemfile.lock
│   ├── lib
│   ├── log
│   ├── Procfile.dev
│   ├── public
│   ├── Rakefile
│   ├── README.md
│   ├── script
│   ├── storage
│   ├── test
│   ├── tmp
│   └── vendor

2. Scaffolding

Rails follows convention over configuration, and it can create the boilerplate code for the models, views and controller for you. For example:

bundle exec rails generate scaffold User name:string nationaility:string date_of_borth:date
bundle exec rails db:migrate

This command creates a User table in the database with the fields as specified, but it also adds the views and controllers for the standard CRUD (create, read update, delete) functions. You can edit this code later to change the functionality as required.

3. Active Record & Rails Console

Rails has a built-in ORM (like python’s sqlalchemy, so you don’t need to write SQL, you can immediately access the database from Ruby objects. We can test this with the build in Rails console:

bundle exec rails c  # start console
User.create(name="Andy", nationality="British") # create a new user and add to the DB

4. Deployment

Rails conventions and batteries-built-in philosophy also extends to deployment – there is no need to write your own Ansible playbook or dockerfile. Rail’s built in solution is called Kamal. This takes code from your github repo, builds a docker image and deploys it to a VPS of your choice, complete with a production server and SSL certificates – just SSH access is needed. There is a minimal amount of configuration required which lives in /config/deploy.yml in the Rails project folder.

Conclusion

Coming from Python, Rails does seem to make setting up and deploying a CRUD type app very straightforward. The downside is that Rails’ heavy reliance on convention can make it harder to understand what is happening under the hood, particularly which variables, helpers, and method names are implicitly available and where they come from. I expect this just needs some time and experience in getting used to!