Mike Slinn

Ruby on Rails / Solidus for E-Commerce

Published 2022-07-22. Last modified 2022-07-23.
Time to read: 7 minutes.

This page is part of the ruby collection.

The internet is an echo chamber. Influencers quote each other. Statistics are often cited without considering how relevant they might be.

The business value of e-commerce platforms is defined by their integrations.

My Goal

I decided to make a prototype e-commerce website for selling digital goods. The website should be quick to create, easy to maintain, and attractive to users.

Contenders

Two of the most popular technologies for e-commerce websites are Ruby on Rails (Rails) and Django, which is based on Python. Many comparisons of these frameworks have been written. I have worked with both of them.

Python is 7.5x as popular as Ruby (48% vs 7%).

Ruby on Rails is approximately as popular as Django (58% vs 55%)
Overall, the net change for the month has the total number of websites using Rails growing by 2,242 and the total number of websites using Django growing by 338.

If we focus on the tendencies inside the web frameworks ecosystem (websites added vs websites dropped), we see that Rails has a 2.5% growth rate and 98.4% retention rate compared to a growth rate of 2.3% and retention rate of 98.3% for Django.

Despite the similar growth and retention rates, Rails currently has a small edge in overall popularity, holding 3.3% of the market share, while Django holds only 0.68%.

Integrations Make the Difference

Most of the comparisons of Rails vs. Django do not consider integrations. That is unfortunate because the business value of an e-commerce platform is largely dependent on how it is integrated with other services. Examples of desirable integrations include authentication and authorization mechanisms, payment processing, content management, etc.

Bespoke integrations are time-consuming, expensive to write, and expensive to maintain. e-commerce platforms that provide quality integrations are more competitive.

Solidus

Solidus provides a componentized approach to Ruby on Rails. It includes a Rails Engine. Solidus is hosted on GitHub. Solidus originated as a fork of Spree (the linked website has an expired SSL certificate).

Integrations that interest me at this time include Payments (PayPal and Stripe), Authentication (Devise and User Roles), Content Management (Static Content), SEO, Sitemap, Klaviyo, Subscriptions, Digital products, Editor, and Social Authentication.

This article is a work in progress. I will update it as I learn more.

Front End

Solidus favors Bootstrap as a frontend, which is fine with me. That said, work has been done to support React.

In 2021, React.js surpassed jQuery as the most commonly used web framework (40% vs. 34%).

I do not agree with calling React or jQuery “web frameworks”. The React website has a better descriptive phrase: a JavaScript library for building user interfaces.

Proof of Concept

I decided to use Solidus on Ubuntu to make a proof of concept (POC) to evaluate the technology.

The Solidus Developer’s Guide is helpful, but it was written for Mac users, using the SQLite database. SQLite is not suitable for production, and it is only somewhat PostgreSQL compatible. I felt that it would be more instructive to evaluate the proof of concept if it used the actual production database.

The following are the steps that I followed to create the POC on Ubuntu using PostgreSQL.

At the time of this writing, the most recently published Solidus gem only supported Rails v6.1.6.1. This post describes how to build a more recent gem that supports Rails 7.

Regarding the front end, I will learn more about what makes sense to use with Solidus as I play with it. This article will be updated as I gain experience.

Installing System Packages

I have previously discussed installing Ruby. You also need to install Node.js because Rails’ asset pipeline compiler requires a JavaScript runtime. The Node.js version is not significant. To install the remaining packages, type:

Shell
$ yes | sudo apt install \
  git imagemagick libpq-dev nodejs npm postgresql postgresql-contrib
Reading package lists... Done
  Building dependency tree... Done
  Reading state information... Done
  postgresql is already the newest version (14+238).
  postgresql-contrib is already the newest version (14+238).
  Setting up liblqr-1-0:amd64 (0.4.2-2.1) ...
  Setting up libde265-0:amd64 (1.0.8-1) ...
  Setting up libjxr-tools (1.2~git20170615.f752187-5) ...
  Setting up libheif1:amd64 (1.12.0-2build1) ...
  Setting up libmagickcore-6.q16-6:amd64 (8:6.9.11.60+dfsg-1.3build2) ...
  Setting up libmagickwand-6.q16-6:amd64 (8:6.9.11.60+dfsg-1.3build2) ...
  Setting up libmagickcore-6.q16-6-extra:amd64 (8:6.9.11.60+dfsg-1.3build2) ...
  Setting up imagemagick-6.q16 (8:6.9.11.60+dfsg-1.3build2) ...
  update-alternatives: using /usr/bin/compare-im6.q16 to provide /usr/bin/compare (compare) in auto mode
  update-alternatives: using /usr/bin/compare-im6.q16 to provide /usr/bin/compare-im6 (compare-im6) in auto mode
  update-alternatives: using /usr/bin/animate-im6.q16 to provide /usr/bin/animate (animate) in auto mode
  update-alternatives: using /usr/bin/animate-im6.q16 to provide /usr/bin/animate-im6 (animate-im6) in auto mode
  update-alternatives: using /usr/bin/convert-im6.q16 to provide /usr/bin/convert (convert) in auto mode
  update-alternatives: using /usr/bin/convert-im6.q16 to provide /usr/bin/convert-im6 (convert-im6) in auto mode
  update-alternatives: using /usr/bin/composite-im6.q16 to provide /usr/bin/composite (composite) in auto mode
  update-alternatives: using /usr/bin/composite-im6.q16 to provide /usr/bin/composite-im6 (composite-im6) in auto mode
  update-alternatives: using /usr/bin/conjure-im6.q16 to provide /usr/bin/conjure (conjure) in auto mode
  update-alternatives: using /usr/bin/conjure-im6.q16 to provide /usr/bin/conjure-im6 (conjure-im6) in auto mode
  update-alternatives: using /usr/bin/import-im6.q16 to provide /usr/bin/import (import) in auto mode
  update-alternatives: using /usr/bin/import-im6.q16 to provide /usr/bin/import-im6 (import-im6) in auto mode
  update-alternatives: using /usr/bin/identify-im6.q16 to provide /usr/bin/identify (identify) in auto mode
  update-alternatives: using /usr/bin/identify-im6.q16 to provide /usr/bin/identify-im6 (identify-im6) in auto mode
  update-alternatives: using /usr/bin/stream-im6.q16 to provide /usr/bin/stream (stream) in auto mode
  update-alternatives: using /usr/bin/stream-im6.q16 to provide /usr/bin/stream-im6 (stream-im6) in auto mode
  update-alternatives: using /usr/bin/display-im6.q16 to provide /usr/bin/display (display) in auto mode
  update-alternatives: using /usr/bin/display-im6.q16 to provide /usr/bin/display-im6 (display-im6) in auto mode
  update-alternatives: using /usr/bin/montage-im6.q16 to provide /usr/bin/montage (montage) in auto mode
  update-alternatives: using /usr/bin/montage-im6.q16 to provide /usr/bin/montage-im6 (montage-im6) in auto mode
  update-alternatives: using /usr/bin/mogrify-im6.q16 to provide /usr/bin/mogrify (mogrify) in auto mode
  update-alternatives: using /usr/bin/mogrify-im6.q16 to provide /usr/bin/mogrify-im6 (mogrify-im6) in auto mode
  Setting up imagemagick (8:6.9.11.60+dfsg-1.3build2) ...
  Processing triggers for fontconfig (2.13.1-4.2ubuntu5) ...
  Processing triggers for desktop-file-utils (0.26-1ubuntu3) ...
  Processing triggers for hicolor-icon-theme (0.17-2) ...
  Processing triggers for gnome-menus (3.36.0-1ubuntu3) ...
  Processing triggers for libc-bin (2.35-0ubuntu3) ...
  Processing triggers for man-db (2.10.2-1) ...
  Processing triggers for mailcap (3.70+nmu1ubuntu1) ... 

The most recent version of Ruby at the time of this writing was 3.1.2, however it would not build on my Ubuntu 22.04 system. The most recent version of Ruby that I was able to build was 3.1.0. To install Ruby 3.1.0 and make it default, type:

Shell
$ rbenv install ruby 3.1.0

$ rbenv global 3.1.0

Install Necessary Gems

Some of the required gems are built after a long compile. If you just installed Ruby, the compilation will take a long time and use 100% of the CPU. What’s more, if you are using ssh to connect to the machine doing the compile, the connection might drop for various reasons. Depending on the hardware, doing this for the first time might take hours.

I ran the build under nice so other processes could continue unimpeded. Nice only throttles the process it manages when other processes request a time slice. If the system load is low, then nice does not throttle the process that it supervises.

I also used nohup to continue the process if the ssh connection dropped. The & at the end of the command line below causes the command-line process to run asynchronously, detached from the console foreground.

Just for interest’s sake, I also measured how long the entire build took with the time command wrapper.

These three bash command wrappers, nohup, time and nice are often used together like this to start a long, CPU-intensive process that won’t get interrupted and won’t overload the system while providing an indication of how much time was required to complete the process.

Because nohup swallows the output and saves it to nohup.out, tee nohup.out displays the build as it progresses. The 1>&2 incantation causes both the gem install command’s STDOUT and STDERR output streams to be piped into tee.

Shell
$ nohup time nice gem install rails 1>&2 | tee nohup.out &
Fetching method_source-1.0.0.gem
Fetching zeitwerk-2.6.0.gem
Fetching activesupport-7.0.3.1.gem
Fetching crass-1.0.6.gem
Fetching loofah-2.18.0.gem
Fetching rails-html-sanitizer-1.4.3.gem
Fetching rails-dom-testing-2.0.3.gem
Fetching rack-2.2.4.gem
Fetching erubi-1.10.0.gem
Fetching builder-3.2.4.gem
Fetching actionview-7.0.3.1.gem
Fetching actionpack-7.0.3.1.gem
Fetching railties-7.0.3.1.gem
Fetching mini_mime-1.1.2.gem
Fetching marcel-1.0.2.gem
Fetching activemodel-7.0.3.1.gem
Fetching activerecord-7.0.3.1.gem
Fetching globalid-1.0.0.gem
Fetching activejob-7.0.3.1.gem
Fetching activestorage-7.0.3.1.gem
Fetching actiontext-7.0.3.1.gem
Fetching mail-2.7.1.gem
Fetching actionmailer-7.0.3.1.gem
Fetching actionmailbox-7.0.3.1.gem
Fetching rails-7.0.3.1.gem
Fetching websocket-extensions-0.1.5.gem
Fetching websocket-driver-0.7.5.gem
Fetching nio4r-2.5.8.gem
Fetching actioncable-7.0.3.1.gem
Successfully installed zeitwerk-2.6.0
Successfully installed method_source-1.0.0
Successfully installed activesupport-7.0.3.1
Successfully installed crass-1.0.6
Successfully installed loofah-2.18.0
Successfully installed rails-html-sanitizer-1.4.3
Successfully installed rails-dom-testing-2.0.3
Successfully installed rack-2.2.4
Successfully installed erubi-1.10.0
Successfully installed builder-3.2.4
Successfully installed actionview-7.0.3.1
Successfully installed actionpack-7.0.3.1
Successfully installed railties-7.0.3.1
Successfully installed mini_mime-1.1.2
Successfully installed marcel-1.0.2
Successfully installed activemodel-7.0.3.1
Successfully installed activerecord-7.0.3.1
Successfully installed globalid-1.0.0
Successfully installed activejob-7.0.3.1
Successfully installed activestorage-7.0.3.1
Successfully installed actiontext-7.0.3.1
Successfully installed mail-2.7.1
Successfully installed actionmailer-7.0.3.1
Successfully installed actionmailbox-7.0.3.1
Successfully installed websocket-extensions-0.1.5
Building native extensions. This could take a while...
Successfully installed websocket-driver-0.7.5
Building native extensions. This could take a while...
Successfully installed nio4r-2.5.8
Successfully installed actioncable-7.0.3.1
Successfully installed rails-7.0.3.1
Parsing documentation for zeitwerk-2.6.0
Installing ri documentation for zeitwerk-2.6.0
Parsing documentation for method_source-1.0.0
Installing ri documentation for method_source-1.0.0
Parsing documentation for activesupport-7.0.3.1
Installing ri documentation for activesupport-7.0.3.1
Parsing documentation for crass-1.0.6
Installing ri documentation for crass-1.0.6
Parsing documentation for loofah-2.18.0
Installing ri documentation for loofah-2.18.0
Parsing documentation for rails-html-sanitizer-1.4.3
Installing ri documentation for rails-html-sanitizer-1.4.3
Parsing documentation for rails-dom-testing-2.0.3
Installing ri documentation for rails-dom-testing-2.0.3
Parsing documentation for rack-2.2.4
Installing ri documentation for rack-2.2.4
Parsing documentation for erubi-1.10.0
Installing ri documentation for erubi-1.10.0
Parsing documentation for builder-3.2.4
Installing ri documentation for builder-3.2.4
Parsing documentation for actionview-7.0.3.1
Installing ri documentation for actionview-7.0.3.1
Parsing documentation for actionpack-7.0.3.1
Installing ri documentation for actionpack-7.0.3.1
Parsing documentation for railties-7.0.3.1
Installing ri documentation for railties-7.0.3.1
Parsing documentation for mini_mime-1.1.2
Installing ri documentation for mini_mime-1.1.2
Parsing documentation for marcel-1.0.2
Installing ri documentation for marcel-1.0.2
Parsing documentation for activemodel-7.0.3.1
Installing ri documentation for activemodel-7.0.3.1
Parsing documentation for activerecord-7.0.3.1
Installing ri documentation for activerecord-7.0.3.1
Parsing documentation for globalid-1.0.0
Installing ri documentation for globalid-1.0.0
Parsing documentation for activejob-7.0.3.1
Installing ri documentation for activejob-7.0.3.1
Parsing documentation for activestorage-7.0.3.1
Installing ri documentation for activestorage-7.0.3.1
Parsing documentation for actiontext-7.0.3.1
Installing ri documentation for actiontext-7.0.3.1
Parsing documentation for mail-2.7.1
Installing ri documentation for mail-2.7.1
Parsing documentation for actionmailer-7.0.3.1
Installing ri documentation for actionmailer-7.0.3.1
Parsing documentation for actionmailbox-7.0.3.1
Installing ri documentation for actionmailbox-7.0.3.1
Parsing documentation for websocket-extensions-0.1.5
Installing ri documentation for websocket-extensions-0.1.5
Parsing documentation for websocket-driver-0.7.5
Installing ri documentation for websocket-driver-0.7.5
Parsing documentation for nio4r-2.5.8
Installing ri documentation for nio4r-2.5.8
Parsing documentation for actioncable-7.0.3.1
Installing ri documentation for actioncable-7.0.3.1
Parsing documentation for rails-7.0.3.1
Installing ri documentation for rails-7.0.3.1
Done installing documentation for zeitwerk, method_source, activesupport, crass, loofah, rails-html-sanitizer, rails-dom-testing, rack, erubi, builder, actionview, actionpack, railties, mini_mime, marcel, activemodel, activerecord, globalid, activejob, activestorage, actiontext, mail, actionmailer, actionmailbox, websocket-extensions, websocket-driver, nio4r, actioncable, rails after 44 seconds
29 gems installed
real XmX.XXXs user XmX.XXXs sys XmX.XXX

If you’re using rbenv, you’ll need to run the following command to make the rails executable available:

Shell
$ rbenv rehash

Configure and Start PostgreSQL

PostgreSQL v14 is the version that is installed by Ubuntu 22.04.

Edit /etc/postgresql/14/main/postgresql.conf and change the following line:

/etc/postgresql/14/main/postgresql.conf
#listen_addresses = 'localhost'

To:

/etc/postgresql/14/main/postgresql.conf
listen_addresses = '*'

I edited /etc/postgresql/14/main/pg_hba.conf and changed the METHOD to trust. This file is read when the database starts and when it receives a SIGHUP signal. The trust value is suitable when security is not an issue, for example, when developing. I removed most of the comments from the file for clarity.

/etc/postgresql/14/main/pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             postgres                                trust
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust

Now I started PostgreSQL v14 (this is the version that is installed by Ubuntu 22.04).

Shell
$ sudo pg_ctlcluster 14 main start

$ sudo service postgresql restart
* Restarting PostgreSQL 14 database server
   ...done. 

Next, I created a Postgres user with the same name as the Rails application.

Shell
$ sudo -u postgres createuser -s solidus_poc

The new PostgreSQL user needed a password. This example uses the password meta-command, but you could also use the ALTER USER command.

Shell
$ sudo -u postgres psql -c '\password solidus_poc'
Enter new password for user "solidus_poc":
Enter it again: 

Create a New Rails Project

Use the rails new command to create a new Rails project. This is the help message:

Shell
$ rails new -h
Usage:
  rails new APP_PATH [options]
Options: [--skip-namespace], [--no-skip-namespace] # Skip namespace (affects only isolated engines) [--skip-collision-check], [--no-skip-collision-check] # Skip collision check -r, [--ruby=PATH] # Path to the Ruby binary of your choice # Default: /home/mslinn/.rbenv/versions/3.1.0/bin/ruby -m, [--template=TEMPLATE] # Path to some application template (can be a filesystem path or URL) -d, [--database=DATABASE] # Preconfigure for selected database (options: mysql/postgresql/sqlite3/oracle/sqlserver/jdbcmysql/jdbcsqlite3/jdbcpostgresql/jdbc) # Default: sqlite3 -G, [--skip-git], [--no-skip-git] # Skip .gitignore file [--skip-keeps], [--no-skip-keeps] # Skip source control .keep files -M, [--skip-action-mailer], [--no-skip-action-mailer] # Skip Action Mailer files [--skip-action-mailbox], [--no-skip-action-mailbox] # Skip Action Mailbox gem [--skip-action-text], [--no-skip-action-text] # Skip Action Text gem -O, [--skip-active-record], [--no-skip-active-record] # Skip Active Record files [--skip-active-job], [--no-skip-active-job] # Skip Active Job [--skip-active-storage], [--no-skip-active-storage] # Skip Active Storage files -C, [--skip-action-cable], [--no-skip-action-cable] # Skip Action Cable files -A, [--skip-asset-pipeline], [--no-skip-asset-pipeline] # Indicates when to generate skip asset pipeline -a, [--asset-pipeline=ASSET_PIPELINE] # Choose your asset pipeline [options: sprockets (default), propshaft] # Default: sprockets -J, [--skip-javascript], [--no-skip-javascript] # Skip JavaScript files [--skip-hotwire], [--no-skip-hotwire] # Skip Hotwire integration [--skip-jbuilder], [--no-skip-jbuilder] # Skip jbuilder gem -T, [--skip-test], [--no-skip-test] # Skip test files [--skip-system-test], [--no-skip-system-test] # Skip system test files [--skip-bootsnap], [--no-skip-bootsnap] # Skip bootsnap gem [--dev], [--no-dev] # Set up the application with Gemfile pointing to your Rails checkout [--edge], [--no-edge] # Set up the application with Gemfile pointing to Rails repository --master, [--main], [--no-main] # Set up the application with Gemfile pointing to Rails repository main branch [--rc=RC] # Path to file containing extra configuration options for rails command [--no-rc], [--no-no-rc] # Skip loading of extra configuration options from .railsrc file [--api], [--no-api] # Preconfigure smaller stack for API only apps [--minimal], [--no-minimal] # Preconfigure a minimal rails app -j, [--javascript=JAVASCRIPT] # Choose JavaScript approach [options: importmap (default), webpack, esbuild, rollup] # Default: importmap -c, [--css=CSS] # Choose CSS processor [options: tailwind, bootstrap, bulma, postcss, sass... check https://github.com/rails/cssbundling-rails] -B, [--skip-bundle], [--no-skip-bundle] # Don't run bundle install
Runtime options: -f, [--force] # Overwrite files that already exist -p, [--pretend], [--no-pretend] # Run but do not make any changes -q, [--quiet], [--no-quiet] # Suppress status output -s, [--skip], [--no-skip] # Skip files that already exist
Rails options: -h, [--help], [--no-help] # Show this help message and quit -v, [--version], [--no-version] # Show Rails version number and quit
Description: The 'rails new' command creates a new Rails application with a default directory structure and configuration at the path you specify.
You can specify extra command-line arguments to be used every time 'rails new' runs in the .railsrc configuration file in your home directory, or in $XDG_CONFIG_HOME/rails/railsrc if XDG_CONFIG_HOME is set.
Note that the arguments specified in the .railsrc file don't affect the defaults values shown above in this help message.
Example: rails new ~/Code/Ruby/weblog
This generates a skeletal Rails installation in ~/Code/Ruby/weblog.

I created a new Rails project called solidus_poc, in a new directory called solidus_poc, under the directory pointed to by the $work environment variable. Note that I specified that the Bootstrap frontend would be used.

Shell
$ cd $work/rails

$ rails new -d postgresql -c bootstrap solidus_poc
exist
  create  README.md
  create  Rakefile
  identical  .ruby-version
  create  config.ru
  create  .gitignore
  create  .gitattributes
  create  Gemfile
  run  git init from "."
  Reinitialized existing Git repository in /var/work/rails/solidus_poc/.git/
  create  app
  create  app/assets/config/manifest.js
  create  app/assets/stylesheets/application.css
  create  app/channels/application_cable/channel.rb
  create  app/channels/application_cable/connection.rb
  create  app/controllers/application_controller.rb
  create  app/helpers/application_helper.rb
  create  app/jobs/application_job.rb
  create  app/mailers/application_mailer.rb
  create  app/models/application_record.rb
  create  app/views/layouts/application.html.erb
  create  app/views/layouts/mailer.html.erb
  create  app/views/layouts/mailer.text.erb
  create  app/assets/images
  create  app/assets/images/.keep
  create  app/controllers/concerns/.keep
  create  app/models/concerns/.keep
  create  bin
  create  bin/rails
  create  bin/rake
  create  bin/setup
  create  config
  create  config/routes.rb
  create  config/application.rb
  create  config/environment.rb
  create  config/cable.yml
  create  config/puma.rb
  create  config/storage.yml
  create  config/environments
  create  config/environments/development.rb
  create  config/environments/production.rb
  create  config/environments/test.rb
  create  config/initializers
  create  config/initializers/assets.rb
  create  config/initializers/content_security_policy.rb
  create  config/initializers/cors.rb
  create  config/initializers/filter_parameter_logging.rb
  create  config/initializers/inflections.rb
  create  config/initializers/new_framework_defaults_7_0.rb
  create  config/initializers/permissions_policy.rb
  create  config/locales
  create  config/locales/en.yml
  create  config/master.key
  append  .gitignore
  create  config/boot.rb
  create  config/database.yml
  create  db
  create  db/seeds.rb
  create  lib
  create  lib/tasks
  create  lib/tasks/.keep
  create  lib/assets
  create  lib/assets/.keep
  create  log
  create  log/.keep
  create  public
  create  public/404.html
  create  public/422.html
  create  public/500.html
  create  public/apple-touch-icon-precomposed.png
  create  public/apple-touch-icon.png
  create  public/favicon.ico
  create  public/robots.txt
  create  tmp
  create  tmp/.keep
  create  tmp/pids
  create  tmp/pids/.keep
  create  tmp/cache
  create  tmp/cache/assets
  create  vendor
  create  vendor/.keep
  create  test/fixtures/files
  create  test/fixtures/files/.keep
  create  test/controllers
  create  test/controllers/.keep
  create  test/mailers
  create  test/mailers/.keep
  create  test/models
  create  test/models/.keep
  create  test/helpers
  create  test/helpers/.keep
  create  test/integration
  create  test/integration/.keep
  create  test/channels/application_cable/connection_test.rb
  create  test/test_helper.rb
  create  test/system
  create  test/system/.keep
  create  test/application_system_test_case.rb
  create  storage
  create  storage/.keep
  create  tmp/storage
  create  tmp/storage/.keep
  remove  config/initializers/cors.rb
  remove  config/initializers/new_framework_defaults_7_0.rb
  run  bundle install
  Fetching gem metadata from https://rubygems.org/...........
  Resolving dependencies..........
  Using rake 13.0.6
  Using concurrent-ruby 1.1.10
  Using mini_mime 1.1.2
  Using strscan 3.0.3
  Using public_suffix 4.0.7
  Using racc 1.6.0
  Using crass 1.0.6
  Using bundler 2.3.18
  Using nio4r 2.5.8
  Using matrix 0.4.2
  Using marcel 1.0.2
  Using digest 3.1.0
  Using thor 1.2.1
  Using zeitwerk 2.6.0
  Using builder 3.2.4
  Using erubi 1.10.0
  Using bindex 0.8.1
  Using msgpack 1.5.3
  Using rubyzip 2.3.2
  Using websocket-extensions 0.1.5
  Using i18n 1.12.0
  Using method_source 1.0.0
  Using childprocess 4.1.0
  Using minitest 5.16.2
  Using timeout 0.3.0
  Using io-console 0.5.11
  Using bootsnap 1.12.0
  Using websocket-driver 0.7.5
  Using puma 5.6.4
  Using websocket 1.2.9
  Using regexp_parser 2.5.0
  Using tzinfo 2.0.4
  Using mail 2.7.1
  Using activesupport 7.0.3.1
  Using nokogiri 1.13.7 (x86_64-linux)
  Using globalid 1.0.0
  Using activemodel 7.0.3.1
  Using pg 1.4.1
  Using loofah 2.18.0
  Using net-protocol 0.1.3
  Using rails-html-sanitizer 1.4.3
  Using net-imap 0.2.3
  Using net-pop 0.1.1
  Using net-smtp 0.3.1
  Using activejob 7.0.3.1
  Using activerecord 7.0.3.1
  Using xpath 3.2.0
  Using reline 0.3.1
  Using addressable 2.8.0
  Using irb 1.4.1
  Using rack 2.2.4
  Using rexml 3.2.5
  Using rack-test 2.0.2
  Using selenium-webdriver 4.3.0
  Using capybara 3.37.1
  Using sprockets 4.1.1
  Using debug 1.6.1
  Using rails-dom-testing 2.0.3
  Using webdrivers 5.0.0
  Using actionview 7.0.3.1
  Using actionpack 7.0.3.1
  Using jbuilder 2.11.5
  Using actioncable 7.0.3.1
  Using activestorage 7.0.3.1
  Using actionmailer 7.0.3.1
  Using actionmailbox 7.0.3.1
  Using sprockets-rails 3.4.2
  Using railties 7.0.3.1
  Using actiontext 7.0.3.1
  Using jsbundling-rails 1.0.3
  Using rails 7.0.3.1
  Using web-console 4.2.0
  Using cssbundling-rails 1.1.1
  Using turbo-rails 1.1.1
  Fetching stimulus-rails 1.1.0
  Installing stimulus-rails 1.1.0
  Bundle complete! 16 Gemfile dependencies, 75 gems now installed.
  Use `bundle info [gemname]` to see where a bundled gem is installed.
  run  bundle binstubs bundler
  rails  javascript:install:esbuild
  Compile into app/assets/builds
  create  app/assets/builds
  create  app/assets/builds/.keep
  append  app/assets/config/manifest.js
  append  .gitignore
  append  .gitignore
  Add JavaScript include tag in application layout
  insert  app/views/layouts/application.html.erb
  Create default entrypoint in app/javascript/application.js
  create  app/javascript
  create  app/javascript/application.js
  Add default package.json
  create  package.json
  Add default Procfile.dev
  create  Procfile.dev
  Ensure foreman is installed
  run  gem install foreman from "."
  Error loading RubyGems plugin "/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/plugins/gem-release_plugin.rb": cannot load such file -- gem/release (LoadError)
  Successfully installed foreman-0.87.2
  Parsing documentation for foreman-0.87.2
  Done installing documentation for foreman after 1 seconds
  1 gem installed
  Add bin/dev to start foreman
  create  bin/dev
  Install esbuild
  run  yarn add esbuild from "."
  yarn add v1.22.19
  info No lockfile found.
  [1/4] Resolving packages...
  [2/4] Fetching packages...
  [3/4] Linking dependencies...
  [4/4] Building fresh packages...
  success Saved lockfile.
  success Saved 2 new dependencies.
  info Direct dependencies
  └─ esbuild@0.14.49
  info All dependencies
  ├─ esbuild-linux-64@0.14.49
  └─ esbuild@0.14.49
  Done in 2.81s.
  Add build script
  run  npm set-script build "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets" from "."
  npm WARN set-script set-script is deprecated, use `npm pkg set scripts.scriptname="cmd" instead.
  run  yarn build from "."
  yarn run v1.22.19
  $ esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets
app/assets/builds/application.js 62b app/assets/builds/application.js.map 93b
Done in 0.19s. rails turbo:install stimulus:install Import Turbo append app/javascript/application.js Install Turbo run yarn add @hotwired/turbo-rails from "." yarn add v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... success Saved lockfile. success Saved 3 new dependencies. info Direct dependencies └─ @hotwired/turbo-rails@7.1.3 info All dependencies ├─ @hotwired/turbo-rails@7.1.3 ├─ @hotwired/turbo@7.1.0 └─ @rails/actioncable@7.0.3 Done in 1.92s. Run turbo:install:redis to switch on Redis and use it in development for turbo streams Create controllers directory create app/javascript/controllers create app/javascript/controllers/index.js create app/javascript/controllers/application.js create app/javascript/controllers/hello_controller.js Import Stimulus controllers append app/javascript/application.js Install Stimulus run yarn add @hotwired/stimulus from "." yarn add v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... success Saved lockfile. success Saved 1 new dependency. info Direct dependencies └─ @hotwired/stimulus@3.1.0 info All dependencies └─ @hotwired/stimulus@3.1.0 Done in 1.66s. rails css:install:bootstrap Build into app/assets/builds exist app/assets/builds identical app/assets/builds/.keep File unchanged! The supplied flag value not found! app/assets/config/manifest.js Stop linking stylesheets automatically gsub app/assets/config/manifest.js File unchanged! The supplied flag value not found! .gitignore File unchanged! The supplied flag value not found! .gitignore Remove app/assets/stylesheets/application.css so build output can take over remove app/assets/stylesheets/application.css Add stylesheet link tag in application layout File unchanged! The supplied flag value not found! app/views/layouts/application.html.erb append Procfile.dev Add bin/dev to start foreman identical bin/dev Install Bootstrap with Bootstrap Icons and Popperjs/core create app/assets/stylesheets/application.bootstrap.scss run yarn add sass bootstrap bootstrap-icons @popperjs/core from "." yarn add v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... success Saved lockfile. success Saved 20 new dependencies. info Direct dependencies ├─ @popperjs/core@2.11.5 ├─ bootstrap-icons@1.9.1 ├─ bootstrap@5.2.0 └─ sass@1.53.0 info All dependencies ├─ @popperjs/core@2.11.5 ├─ anymatch@3.1.2 ├─ binary-extensions@2.2.0 ├─ bootstrap-icons@1.9.1 ├─ bootstrap@5.2.0 ├─ braces@3.0.2 ├─ chokidar@3.5.3 ├─ fill-range@7.0.1 ├─ glob-parent@5.1.2 ├─ immutable@4.1.0 ├─ is-binary-path@2.1.0 ├─ is-extglob@2.1.1 ├─ is-glob@4.0.3 ├─ is-number@7.0.0 ├─ normalize-path@3.0.0 ├─ picomatch@2.3.1 ├─ readdirp@3.6.0 ├─ sass@1.53.0 ├─ source-map-js@1.0.2 └─ to-regex-range@5.0.1 Done in 7.92s. insert config/initializers/assets.rb Appending Bootstrap JavaScript import to default entry point append app/javascript/application.js Add build:css script run npm set-script build:css "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules" from "." npm WARN set-script set-script is deprecated, use `npm pkg set scripts.scriptname="cmd" instead. run yarn build:css from "." yarn run v1.22.19 $ sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules Done in 3.92s.

Make the solidus_poc directory current.

Shell
$ cd solidus_poc

The Rails documentation describes the contents of the generated files in detail.

Commit to a New Git Repo

This is a good time to commit the work to a git repo so far. I used the GitHub CLI to create a repo called solidus_poc, and also set the remote origin in .git/config within the current directory.

Shell
$ gh repo create solidus_poc --public --source=. --remote=upstream
✓ Created repository mslinn/solidus_poc on GitHub 

$ git add -A

$ git commit -m "Initial commit"

$ git push -u origin master

Meet the Solidus Gems

The most recent release of Solidus (v3.1.7) only supports Rails 6.1.x, which was released in January 2021 (18 months ago, as of this writing). However, support for Rails v7.0.3 was merged into Solidus on April 21, 2022. The Solidus developers said the next release might occur in a few weeks. I did not want to wait, so I decided to build the gems from master.

Instead of manually running git clone and pulling down a copy of the repository, I used bundle’s ability to build a local copy of a gem and all its dependencies directly from a git repository.

Several gems are defined in this project. All of them are automatically built:

  • solidus.gemspec
  • solidus_api.gemspec
  • solidus_backend.gemspec
  • solidus_core.gemspec
  • solidus_frontend.gemspec
  • solidus_sample.gemspec

How I Built the Solidus Gems

Building the gems is quick. The freshly built gems are automatically installed locally, along with all their dependencies.

I manually added the following line to the project Gemfile:

Gemfile
gem 'solidus', git: 'https://github.com/solidusio/solidus'

Then I ran bundle install, taking care not to bog down the local machine performing the installation by using the nice command. This caused the solidus gems to be built from the master branch of the GitHub project. Those gems, and their dependencies, were automatically installed:

Shell
$ nohup nice bundle install 1>&2 | tee nohup.out &
Fetching https://github.com/solidusio/solidus
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies....
Using rake 13.0.6
Using minitest 5.16.2
Using rack 2.2.4
Using erubi 1.10.0
Using racc 1.6.0
Using digest 3.1.0
Using nio4r 2.5.8
Using concurrent-ruby 1.1.10
Using builder 3.2.4
Using websocket-extensions 0.1.5
Using marcel 1.0.2
Using mini_mime 1.1.2
Using bundler 2.3.18
Using timeout 0.3.0
Using strscan 3.0.3
Using public_suffix 4.0.7
Using execjs 2.8.1
Using bindex 0.8.1
Using msgpack 1.5.3
Using crass 1.0.6
Using cancancan 3.4.0
Using method_source 1.0.0
Using io-console 0.5.11
Using zeitwerk 2.6.0
Using matrix 0.4.2
Using regexp_parser 2.5.0
Using childprocess 4.1.0
Using climate_control 0.2.0
Using thor 1.2.1
Using ffi 1.15.5
Using tilt 2.0.11
Using mini_magick 4.11.0
Using kaminari-core 1.2.2
Using mime-types-data 3.2022.0105
Using omnes 0.2.2
Using pg 1.4.1
Using stringio 3.0.2
Using rexml 3.2.5
Using rubyzip 2.3.2
Using websocket 1.2.9
Using state_machines 0.5.0
Using truncate_html 0.9.3
Using rack-test 2.0.2
Using nokogiri 1.13.7 (x86_64-linux)
Using puma 5.6.4
Using i18n 1.12.0
Using tzinfo 2.0.4
Using sprockets 4.1.1
Using websocket-driver 0.7.5
Using mail 2.7.1
Using net-protocol 0.1.3
Using addressable 2.8.0
Using autoprefixer-rails 10.4.7.0
Using bootsnap 1.12.0
Using reline 0.3.1
Using terrapin 0.6.0
Using ruby-vips 2.1.4
Using sassc 2.4.0
Using mime-types 3.4.1
Using psych 4.0.4
Using selenium-webdriver 4.3.0
Using loofah 2.18.0
Using irb 1.4.1
Using money 6.16.0
Using activesupport 7.0.3.1
Using handlebars_assets 0.23.9
Using net-imap 0.2.3
Using net-pop 0.1.1
Using net-smtp 0.3.1
Using xpath 3.2.0
Using image_processing 1.12.2
Using webdrivers 5.0.0
Using rails-html-sanitizer 1.4.3
Using debug 1.6.1
Using monetize 1.12.0
Using rails-dom-testing 2.0.3
Using globalid 1.0.0
Using activemodel 7.0.3.1
Using activemerchant 1.126.0
Using activerecord 7.0.3.1
Using state_machines-activemodel 0.8.0
Using acts_as_list 1.0.4
Using awesome_nested_set 3.5.0
Using kt-paperclip 7.1.1
Using kaminari-activerecord 1.2.2
Using ransack 2.6.0
Using discard 1.2.1
Using actionview 7.0.3.1
Using activejob 7.0.3.1
Using actionpack 7.0.3.1
Using carmen 1.1.3
Using capybara 3.37.1
Using state_machines-activerecord 0.8.0
Using jbuilder 2.11.5
Using friendly_id 5.4.2
Using kaminari-actionview 1.2.2
Using actioncable 7.0.3.1
Using activestorage 7.0.3.1
Using actionmailer 7.0.3.1
Using railties 7.0.3.1
Using sprockets-rails 3.4.2
Using cssbundling-rails 1.1.1
Using jsbundling-rails 1.0.3
Using actiontext 7.0.3.1
Using font-awesome-rails 4.7.0.8
Using jquery-rails 4.5.0
Using responders 3.0.1
Using kaminari 1.2.2
Using actionmailbox 7.0.3.1
Using stimulus-rails 1.1.0
Using turbo-rails 1.1.1
Using web-console 4.2.0
Using sassc-rails 2.1.2
Using solidus_core 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230)
Using rails 7.0.3.1
Using canonical-rails 0.2.14
Using solidus_api 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230)
Using solidus_sample 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230)
Using solidus_backend 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230)
Using solidus_frontend 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230)
Using solidus 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230)
Bundle complete! 17 Gemfile dependencies, 121 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed. 

Solidus_core displayed the following Post-install message:

solidus_core post-install message
Post-install message from solidus_core:
-------------------------------------------------------------
                Thank you for using Solidus
-------------------------------------------------------------
If this is a fresh install, don't forget to run the Solidus
installer with the following command:

$ bin/rails g solidus:install

If you are updating Solidus from an older version, please run
the following commands to complete the update:

$ bin/rails g solidus:update

Please, don't forget to look at the CHANGELOG to see what has changed and
whether you need to perform other tasks.

https://github.com/solidusio/solidus/blob/master/CHANGELOG.md

Please report any issues at:
- https://github.com/solidusio/solidus/issues
- http://slack.solidus.io/
-------------------------------------------------------------
Post-install message from solidus_frontend:
----------------------------------------------------------------------------
DEPRECATION WARNING: SolidusFrontend is deprecated. It will be removed from
the solidus meta-package gem in a Solidus v4. Furthermore, its code will be
extracted from https://github.com/solidusio/solidus to a new repo. Once
extracted, you'll need to explicitly add `solidus_frontend` to your Gemfile
in order to continue using it.

For fresh Solidus applications, we recommend you use SolidusStarterFrontend
instead.
----------------------------------------------------------------------------

Let’s take a quick peek at one of the newly built gems:

Shell
$ bundle info solidus
  * solidus (3.2.0.alpha a227230)
  Summary: Full-stack e-commerce framework for Ruby on Rails.
  Homepage: http://solidus.io
  Path: /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/bundler/gems/solidus-a22723079f88 

Following the directions in the post-install message, I typed:

Shell
$ nohup time nice \
  bin/rails generate solidus:install 1>&2 | tee nohup.out &
create  config/initializers/spree.rb
  Installing Active Storage
          rake  active_storage:install
  Copied migration 20220730004449_create_active_storage_tables.active_storage.rb from active_storage
        append  public/robots.txt
         exist  app/assets/images
        create  vendor/assets/javascripts/spree/frontend
        create  vendor/assets/javascripts/spree/backend
        create  vendor/assets/stylesheets/spree/frontend
        create  vendor/assets/stylesheets/spree/backend
        create  vendor/assets/images/spree/frontend
        create  vendor/assets/images/spree/backend
        create  vendor/assets/javascripts/spree/frontend/all.js
        create  vendor/assets/stylesheets/spree/frontend/all.css
        create  vendor/assets/javascripts/spree/backend/all.js
        create  vendor/assets/stylesheets/spree/backend/all.css
        create  app/overrides
Solidus has a default authentication extension that uses Devise. You can find more info at https://github.com/solidusio/solidus_auth_devise.
Would you like to install it? (Y/n)
You can select a payment method to be included in the installation process. Please select a payment method name: [paypal, none] (paypal) append db/seeds.rb copying migrations creating database rake db:create We could not find your database: postgres. Which can be found in the database configuration file located at config/database.yml.
To resolve this issue:
- Did you create the database for this app, or delete it? You may need to create your database. - Has the database name changed? Check your database.yml config has the correct database name.
To create your database, run:
bin/rails db:create Couldn't create 'slinnbooks' database. Please check your configuration. rake aborted! ActiveRecord::NoDatabaseError: We could not find your database: postgres. Which can be found in the database configuration file located at config/database.yml.
To resolve this issue:
- Did you create the database for this app, or delete it? You may need to create your database. - Has the database name changed? Check your database.yml config has the correct database name.
To create your database, run:
bin/rails db:create

Caused by: PG::ConnectionBad: connection to server at "127.0.0.1", port 5432 failed: FATAL: password authentication failed for user "postgres" connection to server at "127.0.0.1", port 5432 failed: FATAL: password authentication failed for user "postgres"
Tasks: TOP => db:create (See full trace by running task with --trace) gemfile solidus_auth_devise gemfile solidus_paypal_commerce_platform run bundle install from "." Fetching gem metadata from https://rubygems.org/......... Resolving dependencies.... Using rake 13.0.6 Using concurrent-ruby 1.1.10 Using rack 2.2.4 Using builder 3.2.4 Using erubi 1.10.0 Using digest 3.1.0 Using crass 1.0.6 Using nio4r 2.5.8 Using minitest 5.16.2 Using public_suffix 4.0.7 Using marcel 1.0.2 Fetching bcrypt 3.1.18 Using racc 1.6.0 Using timeout 0.3.0 Using bundler 2.3.18 Using websocket-extensions 0.1.5 Using execjs 2.8.1 Using mini_mime 1.1.2 Using bindex 0.8.1 Using msgpack 1.5.4 Using strscan 3.0.4 Using cancancan 3.4.0 Using method_source 1.0.0 Using thor 1.2.1 Using zeitwerk 2.6.0 Using matrix 0.4.2 Using regexp_parser 2.5.0 Using childprocess 4.1.0 Using ffi 1.15.5 Using io-console 0.5.11 Using rainbow 3.1.1 Fetching polyglot 0.3.5 Fetching orm_adapter 0.5.0 Using climate_control 0.2.0 Using tilt 2.0.11 Using mini_magick 4.11.0 Using pg 1.4.2 Using mime-types-data 3.2022.0105 Using omnes 0.2.2 Using kaminari-core 1.2.2 Fetching paypalhttp 1.0.1 Using stringio 3.0.2 Using rexml 3.2.5 Using rubyzip 2.3.2 Using websocket 1.2.9 Using i18n 1.12.0 Using truncate_html 0.9.3 Fetching solidus_support 0.9.1 Using state_machines 0.5.0 Using tzinfo 2.0.5 Fetching warden 1.2.9 Using rack-test 2.0.2 Using sprockets 4.1.1 Using puma 5.6.4 Using addressable 2.8.0 Using nokogiri 1.13.8 (x86_64-linux) Using net-protocol 0.1.3 Using websocket-driver 0.7.5 Using autoprefixer-rails 10.4.7.0 Using mail 2.7.1 Using bootsnap 1.13.0 Using ruby-vips 2.1.4 Using sassc 2.4.0 Using terrapin 0.6.0 Using reline 0.3.1 Using mime-types 3.4.1 Using psych 4.0.4 Using selenium-webdriver 4.3.0 Using activesupport 7.0.3.1 Using money 6.16.0 Using handlebars_assets 0.23.9 Installing polyglot 0.3.5 Installing orm_adapter 0.5.0 Using loofah 2.18.0 Using xpath 3.2.0 Installing solidus_support 0.9.1 Installing paypalhttp 1.0.1 Installing warden 1.2.9 Using net-imap 0.2.3 Using net-smtp 0.3.1 Using image_processing 1.12.2 Using irb 1.4.1 Using net-pop 0.1.1 Using rails-dom-testing 2.0.3 Using globalid 1.0.0 Using activemodel 7.0.3.1 Using activemerchant 1.126.0 Using webdrivers 5.0.0 Using monetize 1.12.0 Using carmen 1.1.3 Using rails-html-sanitizer 1.4.3 Using debug 1.6.1 Using activejob 7.0.3.1 Using activerecord 7.0.3.1 Using kt-paperclip 7.1.1 Using state_machines-activemodel 0.8.0 Using actionview 7.0.3.1 Using acts_as_list 1.0.4 Using awesome_nested_set 3.5.0 Using discard 1.2.1 Using friendly_id 5.4.2 Using capybara 3.37.1 Installing bcrypt 3.1.18 with native extensions Using kaminari-activerecord 1.2.2 Using state_machines-activerecord 0.8.0 Using ransack 2.6.0 Using jbuilder 2.11.5 Using kaminari-actionview 1.2.2 Using actionpack 7.0.3.1 Using kaminari 1.2.2 Using actioncable 7.0.3.1 Using railties 7.0.3.1 Using sprockets-rails 3.4.2 Using cssbundling-rails 1.1.1 Using actionmailer 7.0.3.1 Fetching deface 1.9.0 Using activestorage 7.0.3.1 Using font-awesome-rails 4.7.0.8 Using jquery-rails 4.5.0 Using responders 3.0.1 Using stimulus-rails 1.1.0 Using turbo-rails 1.1.1 Using web-console 4.2.0 Using sassc-rails 2.1.2 Using jsbundling-rails 1.0.3 Using actionmailbox 7.0.3.1 Using actiontext 7.0.3.1 Using rails 7.0.3.1 Using canonical-rails 0.2.14 Using solidus_core 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230) Using solidus_api 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230) Using solidus_sample 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230) Using solidus_backend 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230) Using solidus_frontend 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230) Using solidus 3.2.0.alpha from https://github.com/solidusio/solidus (at master@a227230) Fetching paypal-checkout-sdk 1.0.4 Fetching solidus_webhooks 0.4.0 Installing deface 1.9.0 Installing paypal-checkout-sdk 1.0.4 Installing solidus_webhooks 0.4.0 Fetching solidus_paypal_commerce_platform 0.3.2 Installing solidus_paypal_commerce_platform 0.3.2 Fetching devise 4.8.1 Installing devise 4.8.1 Fetching devise-encryptable 0.2.0 Installing devise-encryptable 0.2.0 Fetching solidus_auth_devise 2.5.4 Installing solidus_auth_devise 2.5.4 Bundle complete! 19 Gemfile dependencies, 135 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed. Post-install message from solidus_auth_devise: NOTE: Rails 6 has removed secret_token in favor of secret_key_base, which was deprecated in Rails 5.2. solidus_auth_devise will keep using secret_token, when present, as the pepper. If secret_token is undefined or not available, secret_key_base will be used instead. generate solidus:auth:install --skip_migrations=true rails generate solidus:auth:install --skip_migrations=true /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/solidus_paypal_commerce_platform-0.3.2/lib/solidus_paypal_commerce_platform/engine.rb:18:in `block in <class:Engine>': uninitialized constant SolidusPaypalCommercePlatform::PaymentMethod (NameError)
app.config.spree.payment_methods << SolidusPaypalCommercePlatform::PaymentMethod ^^^^^^^^^^^^^^^ from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/initializable.rb:32:in `instance_exec' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/initializable.rb:32:in `run' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/initializable.rb:61:in `block in run_initializers' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/3.1.0/tsort.rb:228:in `block in tsort_each' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/3.1.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/3.1.0/tsort.rb:431:in `each_strongly_connected_component_from' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/3.1.0/tsort.rb:349:in `block in each_strongly_connected_component' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/3.1.0/tsort.rb:347:in `each' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/3.1.0/tsort.rb:347:in `call' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/3.1.0/tsort.rb:347:in `each_strongly_connected_component' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/3.1.0/tsort.rb:226:in `tsort_each' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/3.1.0/tsort.rb:205:in `tsort_each' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/initializable.rb:60:in `run_initializers' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/application.rb:372:in `initialize!' from /mnt/f/work/rails/solidus_poc/config/environment.rb:5:in `<main>' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.0/lib/zeitwerk/kernel.rb:35:in `require' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/application.rb:348:in `require_environment!' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/command/actions.rb:28:in `require_environment!' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/command/actions.rb:15:in `require_application_and_environment!' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/commands/generate/generate_command.rb:21:in `perform' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/command/base.rb:87:in `perform' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/command.rb:48:in `invoke' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/commands.rb:18:in `<main>' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require' from /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require' from bin/rails:4:in `<main>'

I keep telling myself that one day I will fix this and start again. Sigh.

Define and Create the Database

Set the usernames and passwords for the development, test and production databases in config/database.yml. I removed most of the comments for clarity. Read the actual file's comments, there is a lot of good information in them.

config/database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development: <<: *default database: scalacourses_development #host: localhost password: <%= ENV["SCALACOURSES_DATABASE_PASSWORD_DEV"] %> #port: 5432 #schema_search_path: myapp,sharedapp,public username: scalacourses
# Log levels, in increasing verbosity: # debug5, debug4, debug3, debug2, debug1, # log, notice, warning, error, fatal, and panic # Default is warning. #min_messages: notice
test: <<: *default database: scalacourses_test #host: localhost #port: 5432
production: <<: *default database: scalacourses_production #host: localhost #port: 5432 password: <%= ENV["SCALACOURSES_DATABASE_PASSWORD_PROD"] %> username: scalacourses

Use environment variable to set values for SCALACOURSES_DATABASE_PASSWORD_DEV, and perhaps SCALACOURSES_DATABASE_PASSWORD_PROD

~/.bashrc
export SCALACOURSES_DATABASE_PASSWORD_DEV=my_secret

Define the environment variable in the current shell, then launch Rails.

Shell
$ source ~/.bashrc

Here is the help message for creating the datatabase using rake.

Shell
$ rake db:create -h
rake [-f rakefile] {options} targets...
Options are ... --backtrace=[OUT] Enable full backtrace. OUT can be stderr (default) or stdout. --comments Show commented tasks only --job-stats [LEVEL] Display job statistics. LEVEL=history displays a complete job list --rules Trace the rules resolution. --suppress-backtrace PATTERN Suppress backtrace lines matching regexp PATTERN. Ignored if --trace is on. -A, --all Show all tasks, even uncommented ones (in combination with -T or -D) -B, --build-all Build all prerequisites, including those which are up-to-date. -C, --directory [DIRECTORY] Change to DIRECTORY before doing anything. -D, --describe [PATTERN] Describe the tasks (matching optional PATTERN), then exit. -e, --execute CODE Execute some Ruby code and exit. -E, --execute-continue CODE Execute some Ruby code, then continue with normal task processing. -f, --rakefile [FILENAME] Use FILENAME as the rakefile to search for. -G, --no-system, --nosystem Use standard project Rakefile search paths, ignore system wide rakefiles. -g, --system Using system wide (global) rakefiles (usually '~/.rake/*.rake'). -I, --libdir LIBDIR Include LIBDIR in the search path for required modules. -j, --jobs [NUMBER] Specifies the maximum number of tasks to execute in parallel. (default is number of CPU cores + 4) -m, --multitask Treat all tasks as multitasks. -n, --dry-run Do a dry run without executing actions. -N, --no-search, --nosearch Do not search parent directories for the Rakefile. -P, --prereqs Display the tasks and dependencies, then exit. -p, --execute-print CODE Execute some Ruby code, print the result, then exit. -q, --quiet Do not log messages to standard output. -r, --require MODULE Require MODULE before executing rakefile. -R, --rakelibdir RAKELIBDIR, Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib') --rakelib -s, --silent Like --quiet, but also suppresses the 'in directory' announcement. -t, --trace=[OUT] Turn on invoke/execute tracing, enable full backtrace. OUT can be stderr (default) or stdout. -T, --tasks [PATTERN] Display the tasks (matching optional PATTERN) with descriptions, then exit. -AT combination displays all of tasks contained no description. -v, --verbose Log message to standard output. -V, --version Display the program version. -W, --where [PATTERN] Describe the tasks (matching optional PATTERN), then exit. -X, --no-deprecation-warnings Disable the deprecation warnings. -h, -H, --help Display this help message.

Create the development database (scalacourses_development) mentioned in the above configuration file.

Shell
$ rake db:create
Created database 'scalacourses' 

Run Rails Application

Start the Ruby on Rails application.

Shell
$ bin/rails server
=> Booting Puma
  => Rails 7.0.3.1 application starting in development
  => Run `bin/rails server --help` for more startup options
  Puma starting in single mode...
  * Puma version: 5.6.4 (ruby 3.1.0-p0) ("Birdie's Version")
  *  Min threads: 5
  *  Max threads: 5
  *  Environment: development
  *          PID: 23159
  * Listening on http://127.0.0.1:3000
  * Listening on http://[::1]:3000
  Use Ctrl-C to stop 

View the running Rails app in a web browser, such as Google Chrome, Firefox or lynx:

Shell
$ firefox localhost:3000 &

The page should look like this:

As the web browser loads the front page of the new Rails app, notice that the output of the Rails server now includes:

Shell
Started GET "/" for ::1 at 2022-07-16 21:04:46 -0400
Processing by Rails::WelcomeController#index as HTML
  Rendering /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/templates/rails/welcome/index.html.erb
  Rendered /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/railties-7.0.3.1/lib/rails/templates/rails/welcome/index.html.erb (Duration: 10.8ms | Allocations: 545)
Completed 200 OK in 65ms (Views: 33.0ms | ActiveRecord: 0.0ms | Allocations: 4124) 

References

  1. Django Vs Ruby on Rails – Which Framework is Best for 2022?
  2. JetBrains Django Developer Survey 2021
  3. Ruby on Rails vs Django Comparison: Choosing Best Web Framework
  4. Django vs Rails in 2022: Comparison Performance Frameworks

About the Author

I, Mike Slinn, have been working with Ruby for a long time now. Back in 2005, I was the product marketing manager at CodeGear (the company was formerly known as Borland) for their 3rd Rail IDE. 3rd Rail supported Ruby and Ruby on Rails at launch.

In 2006, I co-chaired the Silicon Valley Ruby Conference on behalf of the SD Forum in Silicon Valley. As you can see, I have the t-shirt. I was the sole chairman of the 2007 Silicon Valley Ruby Conference.

Several court cases have come my way over the years in my capacity as a software expert witness. The court cases featured questions about IP misappropriation for Ruby on Rails programs. You can read about my experience as a software expert if that interests you.

I currently enjoy writing Jekyll plugins in Ruby for this website and others, as well as Ruby utilities.



* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.