Rails 7.1 with Ruby 3.2 on Windows: It just works!

Rails 7.1 was released a couple of days back and as a Ruby user primarily on Windows, I was keen to see if it works and runs on Windows.

Thanks to the stellar work of everyone involved, it just works. In short, all you need to do is as below:

  1. RubyInstaller – Download and install a supported version of Ruby on your Windows computer: Ruby 3.0.x | Ruby 3.1.x | Ruby 3.2.x
  2. Open a console window, and follow the commands below.
$ gem install rails
$ rails new hello

Once done, go on in to the hello folder and start the Rails Server

ruby bin\rails server

Then, open a web browser and take a look at http://localhost:3000/ to be greeted with this.

I was expecting to document some workarounds and problems I faced but at least at the very beginning, there was nothing. So, I decided to continue on to a part of the Rails Getting Started tutorial.

So, what’s next? Literally, everything! The basic application uses sqlite3 and you might want to use PostgreSQL – you can either install it directly or set it up without an installation.

Detailed steps

Let’s start by seeing the Ruby version we have.

$ ruby -v
ruby 3.2.0 (2022-12-25 revision a528908271) [x64-mingw-ucrt]

Next, install Rails.

$ gem install rails
Fetching zeitwerk-2.6.12.gem
Fetching rackup-2.1.0.gem
Fetching thor-1.2.2.gem
Fetching rack-3.0.8.gem
Fetching minitest-5.20.0.gem
Fetching tzinfo-2.0.6.gem
Fetching connection_pool-2.4.1.gem
Fetching crass-1.0.6.gem
Fetching activesupport-7.1.0.gem
Fetching nokogiri-1.15.4-x64-mingw-ucrt.gem
Fetching loofah-2.21.3.gem
Fetching rails-html-sanitizer-1.6.0.gem
Fetching builder-3.2.4.gem
Fetching rails-dom-testing-2.2.0.gem
Fetching rack-test-2.1.0.gem
Fetching rack-session-2.0.0.gem
Fetching erubi-1.12.0.gem
Fetching marcel-1.0.2.gem
Fetching actionview-7.1.0.gem
Fetching actionpack-7.1.0.gem
Fetching railties-7.1.0.gem
Fetching timeout-0.4.0.gem
Fetching activemodel-7.1.0.gem
Fetching activerecord-7.1.0.gem
Fetching globalid-1.2.1.gem
Fetching activejob-7.1.0.gem
Fetching activestorage-7.1.0.gem
Fetching websocket-extensions-0.1.5.gem
Fetching actiontext-7.1.0.gem
Fetching mini_mime-1.1.5.gem
Fetching mail-2.8.1.gem
Fetching actionmailer-7.1.0.gem
Fetching actionmailbox-7.1.0.gem
Fetching rails-7.1.0.gem
Fetching websocket-driver-0.7.6.gem
Fetching nio4r-2.5.9.gem
Fetching actioncable-7.1.0.gem
Successfully installed zeitwerk-2.6.12
Successfully installed thor-1.2.2
Successfully installed rack-3.0.8
rackup's executable "rackup" conflicts with rack
Overwrite the executable? [yN]  y
Successfully installed rackup-2.1.0
Successfully installed tzinfo-2.0.6
Successfully installed minitest-5.20.0
Successfully installed connection_pool-2.4.1
Successfully installed activesupport-7.1.0
Successfully installed nokogiri-1.15.4-x64-mingw-ucrt
Successfully installed crass-1.0.6
Successfully installed loofah-2.21.3
Successfully installed rails-html-sanitizer-1.6.0
Successfully installed rails-dom-testing-2.2.0
Successfully installed rack-test-2.1.0
Successfully installed rack-session-2.0.0
Successfully installed erubi-1.12.0
Successfully installed builder-3.2.4
Successfully installed actionview-7.1.0
Successfully installed actionpack-7.1.0
Successfully installed railties-7.1.0
Successfully installed marcel-1.0.2
Successfully installed timeout-0.4.0
Successfully installed activemodel-7.1.0
Successfully installed activerecord-7.1.0
Successfully installed globalid-1.2.1
Successfully installed activejob-7.1.0
Successfully installed activestorage-7.1.0
Successfully installed actiontext-7.1.0
Successfully installed mini_mime-1.1.5
Successfully installed mail-2.8.1
Successfully installed actionmailer-7.1.0
Successfully installed actionmailbox-7.1.0
Successfully installed websocket-extensions-0.1.5
Temporarily enhancing PATH for MSYS/MINGW...
Building native extensions. This could take a while...
Successfully installed websocket-driver-0.7.6
Building native extensions. This could take a while...
Successfully installed nio4r-2.5.9
Successfully installed actioncable-7.1.0
Successfully installed rails-7.1.0
Parsing documentation for zeitwerk-2.6.12
Installing ri documentation for zeitwerk-2.6.12
Parsing documentation for thor-1.2.2
Installing ri documentation for thor-1.2.2
Parsing documentation for rack-3.0.8
Installing ri documentation for rack-3.0.8
Parsing documentation for rackup-2.1.0
Installing ri documentation for rackup-2.1.0
Parsing documentation for tzinfo-2.0.6
Installing ri documentation for tzinfo-2.0.6
Parsing documentation for minitest-5.20.0
Couldn't find file to include 'README.rdoc' from lib/minitest.rb
Installing ri documentation for minitest-5.20.0
Parsing documentation for connection_pool-2.4.1
Installing ri documentation for connection_pool-2.4.1
Parsing documentation for activesupport-7.1.0
Couldn't find file to include 'activesupport/README.rdoc' from lib/active_support.rb
Installing ri documentation for activesupport-7.1.0
Parsing documentation for nokogiri-1.15.4-x64-mingw-ucrt
Installing ri documentation for nokogiri-1.15.4-x64-mingw-ucrt
Parsing documentation for crass-1.0.6
Installing ri documentation for crass-1.0.6
Parsing documentation for loofah-2.21.3
Installing ri documentation for loofah-2.21.3
Parsing documentation for rails-html-sanitizer-1.6.0
Installing ri documentation for rails-html-sanitizer-1.6.0
Parsing documentation for rails-dom-testing-2.2.0
Installing ri documentation for rails-dom-testing-2.2.0
Parsing documentation for rack-test-2.1.0
Installing ri documentation for rack-test-2.1.0
Parsing documentation for rack-session-2.0.0
Installing ri documentation for rack-session-2.0.0
Parsing documentation for erubi-1.12.0
Installing ri documentation for erubi-1.12.0
Parsing documentation for builder-3.2.4
Installing ri documentation for builder-3.2.4
Parsing documentation for actionview-7.1.0
Couldn't find file to include 'actionview/README.rdoc' from lib/action_view.rb
Installing ri documentation for actionview-7.1.0
Parsing documentation for actionpack-7.1.0
Installing ri documentation for actionpack-7.1.0
Parsing documentation for railties-7.1.0
Installing ri documentation for railties-7.1.0
Parsing documentation for marcel-1.0.2
Installing ri documentation for marcel-1.0.2
Parsing documentation for timeout-0.4.0
Installing ri documentation for timeout-0.4.0
Parsing documentation for activemodel-7.1.0
Couldn't find file to include 'activemodel/README.rdoc' from lib/active_model.rb
Installing ri documentation for activemodel-7.1.0
Parsing documentation for activerecord-7.1.0
Couldn't find file to include 'activerecord/README.rdoc' from lib/active_record.rb
Installing ri documentation for activerecord-7.1.0
Parsing documentation for globalid-1.2.1
Installing ri documentation for globalid-1.2.1
Parsing documentation for activejob-7.1.0
Couldn't find file to include 'activejob/README.md' from lib/active_job.rb
Installing ri documentation for activejob-7.1.0
Parsing documentation for activestorage-7.1.0
Couldn't find file to include 'activestorage/README.md' from lib/active_storage.rb
Installing ri documentation for activestorage-7.1.0
Parsing documentation for actiontext-7.1.0
Couldn't find file to include 'actiontext/README.md' from lib/action_text.rb
Installing ri documentation for actiontext-7.1.0
Parsing documentation for mini_mime-1.1.5
Installing ri documentation for mini_mime-1.1.5
Parsing documentation for mail-2.8.1
Installing ri documentation for mail-2.8.1
Parsing documentation for actionmailer-7.1.0
Couldn't find file to include 'actionmailer/README.rdoc' from lib/action_mailer.rb
Installing ri documentation for actionmailer-7.1.0
Parsing documentation for actionmailbox-7.1.0
Couldn't find file to include 'actionmailbox/README.md' from lib/action_mailbox.rb
Installing ri documentation for actionmailbox-7.1.0
Parsing documentation for websocket-extensions-0.1.5
Installing ri documentation for websocket-extensions-0.1.5
Parsing documentation for websocket-driver-0.7.6
Installing ri documentation for websocket-driver-0.7.6
Parsing documentation for nio4r-2.5.9
Installing ri documentation for nio4r-2.5.9
Parsing documentation for actioncable-7.1.0
Couldn't find file to include 'actioncable/README.md' from lib/action_cable.rb
Installing ri documentation for actioncable-7.1.0
Parsing documentation for rails-7.1.0
Installing ri documentation for rails-7.1.0
Done installing documentation for zeitwerk, thor, rack, rackup, tzinfo, minitest, connection_pool, activesupport, nokogiri, crass, loofah, rails-html-sanitizer, rails-dom-testing, rack-test, rack-session, erubi, builder, actionview, actionpack, railties, marcel, timeout, activemodel, activerecord, globalid, activejob, activestorage, actiontext, mini_mime, mail, actionmailer, actionmailbox, websocket-extensions, websocket-driver, nio4r, actioncable, rails after 79 seconds
37 gems installed

You may have noticed some lines like these

Couldn't find file to include 'activemodel/README.rdoc' from lib/active_model.rb
Couldn't find file to include 'activerecord/README.rdoc' from lib/active_record.rb
Couldn't find file to include 'activejob/README.md' from lib/active_job.rb
Couldn't find file to include 'activestorage/README.md' from lib/active_storage.rb
...

This is unexpected and I opened an issue on the Rails GitHub for this – it should be resolved by the time 7.1.1 lands.

Next, create a new project.

$ rails new hello
      create
      create  README.md
      create  Rakefile
      create  .ruby-version
      create  config.ru
      create  .gitignore
      create  .gitattributes
      create  Gemfile
         run  git init from "."
Initialized empty Git repository in D:/projects/rails/rails71-try/hello/.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  Dockerfile
      create  .dockerignore
      create  bin/docker-entrypoint
      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_1.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_1.rb
         run  bundle install
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...
Fetching racc 1.7.1
Fetching bigdecimal 3.1.4
Fetching bindex 0.8.1
Fetching msgpack 1.7.2
Fetching regexp_parser 2.8.1
Fetching stringio 3.0.8
Fetching rexml 3.2.6
Fetching rubyzip 2.3.2
Installing bindex 0.8.1 with native extensions
Installing racc 1.7.1 with native extensions
Installing stringio 3.0.8 with native extensions
Installing msgpack 1.7.2 with native extensions
Installing bigdecimal 3.1.4 with native extensions
Installing rubyzip 2.3.2
Installing regexp_parser 2.8.1
Fetching websocket 1.2.10
Installing rexml 3.2.6
Installing websocket 1.2.10
Fetching sqlite3 1.6.6 (x64-mingw-ucrt)
Fetching puma 6.4.0
Fetching sprockets 4.2.1
Installing puma 6.4.0 with native extensions
Installing sprockets 4.2.1
Installing sqlite3 1.6.6 (x64-mingw-ucrt)
Fetching reline 0.3.9
Fetching tzinfo-data 1.2023.3
Installing reline 0.3.9
Fetching net-imap 0.4.0
Fetching net-smtp 0.4.0
Installing tzinfo-data 1.2023.3
Installing net-imap 0.4.0
Installing net-smtp 0.4.0
Fetching selenium-webdriver 4.13.1
Fetching psych 5.1.0
Installing psych 5.1.0 with native extensions
Fetching xpath 3.2.0
Installing xpath 3.2.0
Fetching capybara 3.39.2
Installing capybara 3.39.2
Installing selenium-webdriver 4.13.1
Fetching irb 1.8.1
Installing irb 1.8.1
Fetching debug 1.8.0
Installing debug 1.8.0 with native extensions
Fetching bootsnap 1.16.0
Installing bootsnap 1.16.0 with native extensions
Fetching jbuilder 2.11.5
Fetching sprockets-rails 3.4.2
Fetching importmap-rails 1.2.1
Fetching stimulus-rails 1.2.2
Fetching turbo-rails 1.4.0
Fetching web-console 4.2.1
Installing jbuilder 2.11.5
Installing sprockets-rails 3.4.2
Installing web-console 4.2.1
Installing importmap-rails 1.2.1
Installing stimulus-rails 1.2.2
Installing turbo-rails 1.4.0
Bundle complete! 14 Gemfile dependencies, 83 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
         run  bundle lock --add-platform=x86_64-linux
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Writing lockfile to d:/projects/rails/rails71-try/hello/Gemfile.lock
         run  bundle binstubs bundler
       rails  importmap:install
       apply  C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/importmap-rails-1.2.1/lib/install/install.rb
  Add Importmap include tags in application layout
      insert    app/views/layouts/application.html.erb
  Create application.js module as entrypoint
      create    app/javascript/application.js
  Use vendor/javascript for downloaded pins
      create    vendor/javascript
      create    vendor/javascript/.keep
  Ensure JavaScript files are in the Sprocket manifest
      append    app/assets/config/manifest.js
  Configure importmap paths in config/importmap.rb
      create    config/importmap.rb
  Copying binstub
      create    bin/importmap
         run  bundle install
Bundle complete! 14 Gemfile dependencies, 83 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
         run  bundle lock --add-platform=x86_64-linux
Writing lockfile to d:/projects/rails/rails71-try/hello/Gemfile.lock
       rails  turbo:install stimulus:install
       apply  C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/turbo-rails-1.4.0/lib/install/turbo_with_importmap.rb
  Import Turbo
      append    app/javascript/application.js
  Pin Turbo
      append    config/importmap.rb
         run  bundle install
Bundle complete! 14 Gemfile dependencies, 83 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
         run  bundle lock --add-platform=x86_64-linux
Writing lockfile to d:/projects/rails/rails71-try/hello/Gemfile.lock
Run turbo:install:redis to switch on Redis and use it in development for turbo streams
       apply  C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/stimulus-rails-1.2.2/lib/install/stimulus_with_importmap.rb
  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
  Pin Stimulus
  Appending: pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true"
      append    config/importmap.rb
  Appending: pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
      append    config/importmap.rb
  Pin all controllers
  Appending: pin_all_from "app/javascript/controllers", under: "controllers"
      append    config/importmap.rb
         run  bundle install
Bundle complete! 14 Gemfile dependencies, 83 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
         run  bundle lock --add-platform=x86_64-linux
Writing lockfile to d:/projects/rails/rails71-try/hello/Gemfile.lock

This is where we see the one warning and comment:

The system cannot find the path specified.
Run turbo:install:redis to switch on Redis and use it in development for turbo streams

Now, move into that folder (hello in our case) and start the server by doing ruby bin\rails server in that directory. Remember to hit Ctrl-C to shut down the server once you’re done using it.

$ ruby bin\rails server
=> Booting Puma
=> Rails 7.1.0 application starting in development
=> Run `bin/rails server --help` for more startup options
*** SIGUSR2 not implemented, signal based restart unavailable!
*** SIGUSR1 not implemented, signal based restart unavailable!
*** SIGHUP not implemented, signal based logs reopening unavailable!
Puma starting in single mode...
* Puma version: 6.4.0 (ruby 3.2.0-p0) ("The Eagle of Durango")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 31224
* Listening on http://[::1]:3000
* Listening on http://127.0.0.1:3000
Use Ctrl-C to stop

After this, you should be able to go to http://localhost:3000 and see the page below.

Rails 7.0 added a new up method that can be used to check if the Rails stack has booted successfully. So, you can head on over to http://localhost:3000/up and see a green page.

You can now continue with the Getting Started tutorial, and I did the following.

Continuing the Tutorial

Following the Rails Getting Started tutorial, I did the following:

  • Added the route
  • Added the controller
  • Updated the view
$ ruby bin\rails generate controller Articles index --skip-routes
      create  app/controllers/articles_controller.rb
      invoke  erb
      create    app/views/articles
      create    app/views/articles/index.html.erb
      invoke  test_unit
      create    test/controllers/articles_controller_test.rb
      invoke  helper
      create    app/helpers/articles_helper.rb
      invoke    test_unit

We are then greeted with this, as expected.

Next, we add the model.

$ ruby bin\rails generate model Article title:string body:text
      invoke  active_record
      create    db/migrate/20231007083851_create_articles.rb
      create    app/models/article.rb
      invoke    test_unit
      create      test/models/article_test.rb
      create      test/fixtures/articles.yml

and run db:migrate as below:

$ ruby bin\rails db:migrate
== 20231007083851 CreateArticles: migrating ===================================
-- create_table(:articles)
   -> 0.0019s
== 20231007083851 CreateArticles: migrated (0.0022s) ==========================

Finally, we added two articles using rails/console:

irb(main):003> article = Article.new(title: "Hello Rails", body: "I am on Rails!")
=> #<Article:0x00000130a74e2428 id: nil, title: "Hello Rails", body: "I am on Rails!", created_at: nil, updated_at:...
irb(main):004> article.save
  TRANSACTION (0.1ms)  begin transaction
  Article Create (0.6ms)  INSERT INTO "articles" ("title", "body", "created_at", "updated_at") VALUES (?, ?, ?, ?) RETURNING "id"  [["title", "Hello Rails"], ["body", "I am on Rails!"], ["created_at", "2023-10-07 09:03:55.042688"], ["updated_at", "2023-10-07 09:03:55.042688"]]
  TRANSACTION (9.4ms)  commit transaction
=> true
irb(main):005> article = Article.new(title: "Hello Ruby 3", body: "New Ruby brings more")
=>
#<Article:0x00000130a77ad0e0
...
irb(main):006> article.save
  TRANSACTION (0.1ms)  begin transaction
  Article Create (0.6ms)  INSERT INTO "articles" ("title", "body", "created_at", "updated_at") VALUES (?, ?, ?, ?) RETURNING "id"  [["title", "Hello Ruby 3"], ["body", "New Ruby brings more"], ["created_at", "2023-10-07 09:04:06.248810"], ["updated_at", "2023-10-07 09:04:06.248810"]]
  TRANSACTION (0.1ms)  commit transaction
=> true

Finally, off to the http://localhost:3000/articles and you will see this.

We are ready for more! If you have any comments, please leave them below so that we can improve this page.

On a side note, while the post was originally intended to just check if everything works fine on Windows, it resulted in:

So, I’m pretty happy how it has turned out.

comments powered by Disqus