Rails 8.0 was released just a few days back and as a user primarily on Windows, I was keen to see it all works and runs on Windows. I had done this check previously with Rails 7.1 on Ruby 3.2 on Windows and it had worked fine. Thanks to the stellar work of everyone involved, it just works. Let’s see a few more details below.
In short, all you need to do is as below:
- RubyInstaller – Download and install a supported version of Ruby on your Windows computer: I’m going to install Ruby 3.3.x as explained here but you can also follow instructions for Ruby 3.2.x | Ruby 3.1.x | Ruby 3.0.x
- Open a console window, and follow the commands below.
$ gem install rails
$ rails new hello8
If you run into an error at this stage with installing psych
, do a gem update
and it will probably get resolved since the installation will happen fine from the command line now, and bundle
after rails new
will pick up the installed version.
Once done, go on in to the hello8
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.3.0 (2023-12-25 revision 5124f9ac75) [x64-mingw-ucrt]
Next, install Rails.
$ gem install rails
$ gem install rails
Fetching rack-3.1.8.gem
Fetching uri-1.0.2.gem
Fetching minitest-5.25.1.gem
Fetching concurrent-ruby-1.3.4.gem
Fetching activesupport-8.0.0.gem
Fetching actionview-8.0.0.gem
Fetching actionpack-8.0.0.gem
Fetching railties-8.0.0.gem
Fetching activemodel-8.0.0.gem
Fetching activerecord-8.0.0.gem
Fetching activejob-8.0.0.gem
Fetching activestorage-8.0.0.gem
Fetching actiontext-8.0.0.gem
Fetching actionmailer-8.0.0.gem
Fetching actionmailbox-8.0.0.gem
Fetching actioncable-8.0.0.gem
Fetching rails-8.0.0.gem
Successfully installed rack-3.1.8
Successfully installed uri-1.0.2
Successfully installed concurrent-ruby-1.3.4
Successfully installed minitest-5.25.1
Successfully installed activesupport-8.0.0
Successfully installed actionview-8.0.0
Successfully installed actionpack-8.0.0
Successfully installed railties-8.0.0
Successfully installed activemodel-8.0.0
Successfully installed activerecord-8.0.0
Successfully installed activejob-8.0.0
Successfully installed activestorage-8.0.0
Successfully installed actiontext-8.0.0
Successfully installed actionmailer-8.0.0
Successfully installed actionmailbox-8.0.0
Successfully installed actioncable-8.0.0
Successfully installed rails-8.0.0
Parsing documentation for rack-3.1.8
Installing ri documentation for rack-3.1.8
Parsing documentation for uri-1.0.2
Installing ri documentation for uri-1.0.2
Parsing documentation for concurrent-ruby-1.3.4
Installing ri documentation for concurrent-ruby-1.3.4
Parsing documentation for minitest-5.25.1
Couldn't find file to include 'README.rdoc' from lib/minitest.rb
Installing ri documentation for minitest-5.25.1
Parsing documentation for activesupport-8.0.0
Installing ri documentation for activesupport-8.0.0
Parsing documentation for actionview-8.0.0
Installing ri documentation for actionview-8.0.0
Parsing documentation for actionpack-8.0.0
Installing ri documentation for actionpack-8.0.0
Parsing documentation for railties-8.0.0
Installing ri documentation for railties-8.0.0
Parsing documentation for activemodel-8.0.0
Installing ri documentation for activemodel-8.0.0
Parsing documentation for activerecord-8.0.0
Installing ri documentation for activerecord-8.0.0
Parsing documentation for activejob-8.0.0
Installing ri documentation for activejob-8.0.0
Parsing documentation for activestorage-8.0.0
Installing ri documentation for activestorage-8.0.0
Parsing documentation for actiontext-8.0.0
Installing ri documentation for actiontext-8.0.0
Parsing documentation for actionmailer-8.0.0
Installing ri documentation for actionmailer-8.0.0
Parsing documentation for actionmailbox-8.0.0
Installing ri documentation for actionmailbox-8.0.0
Parsing documentation for actioncable-8.0.0
Installing ri documentation for actioncable-8.0.0
Parsing documentation for rails-8.0.0
Installing ri documentation for rails-8.0.0
Done installing documentation for rack, uri, concurrent-ruby, minitest, activesupport, actionview, actionpack, railties, activemodel, activerecord, activejob, activestorage, actiontext, actionmailer, actionmailbox, actioncable, rails after 93 seconds
17 gems installed
This time it installed fewer gems for me than previously – it’s probably because some of the dependencies are older installed on my PC since I was using rails main for development a few months back.
You may have noticed this:
Parsing documentation for minitest-5.25.1
Couldn't find file to include 'README.rdoc' from lib/minitest.rb
This is unexpected and there were many more gems with these problems earlier. I had opened an issue on the Rails GitHub for this – most of the earlier list has been resolved, but the warning on minitest still remains.
Quick check – what version of Rails do we have?
$ rails -v
Rails 8.0.0
Good! Now, let’s create a new project.
$ rails new hello8
...
run bundle install --quiet
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory:
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/psych-5.2.0/ext/psych
D:/Ruby33-x64/bin/ruby.exe extconf.rb
checking for pkg-config for yaml-0.1... not found
checking for yaml.h... no
yaml.h not found
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include=${opt-dir}/include
--without-opt-include
--with-opt-lib=${opt-dir}/lib
--without-opt-lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=D:/Ruby33-x64/bin/$(RUBY_BASE_NAME)
--with-libyaml-source-dir
--without-libyaml-source-dir
--with-yaml-0.1-dir
--without-yaml-0.1-dir
--with-yaml-0.1-include=${yaml-0.1-dir}/include
--without-yaml-0.1-include
--with-yaml-0.1-lib=${yaml-0.1-dir}/lib
--without-yaml-0.1-lib
--with-yaml-0.1-config
--without-yaml-0.1-config
--with-pkg-config
--without-pkg-config
--with-libyaml-dir
--without-libyaml-dir
--with-libyaml-include=${libyaml-dir}/include
--without-libyaml-include
--with-libyaml-lib=${libyaml-dir}/lib
--without-libyaml-lib
To see why this extension failed to compile, please check the mkmf.log which can
be found here:
D:/Ruby33-x64/lib/ruby/gems/3.3.0/extensions/x64-mingw-ucrt/3.3.0/psych-5.2.0/mkmf.log
extconf failed, exit code 1
Gem files will remain installed in
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/psych-5.2.0 for inspection.
Results logged to
D:/Ruby33-x64/lib/ruby/gems/3.3.0/extensions/x64-mingw-ucrt/3.3.0/psych-5.2.0/gem_make.out
D:/Ruby33-x64/lib/ruby/3.3.0/rubygems/ext/builder.rb:125:in `run'
D:/Ruby33-x64/lib/ruby/3.3.0/rubygems/ext/ext_conf_builder.rb:28:in `build'
D:/Ruby33-x64/lib/ruby/3.3.0/rubygems/ext/builder.rb:193:in `build_extension'
D:/Ruby33-x64/lib/ruby/3.3.0/rubygems/ext/builder.rb:227:in `block in
build_extensions'
D:/Ruby33-x64/lib/ruby/3.3.0/rubygems/ext/builder.rb:224:in `each'
D:/Ruby33-x64/lib/ruby/3.3.0/rubygems/ext/builder.rb:224:in `build_extensions'
D:/Ruby33-x64/lib/ruby/3.3.0/rubygems/installer.rb:852:in `build_extensions'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/rubygems_gem_installer.rb:76:in
`build_extensions'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/rubygems_gem_installer.rb:28:in
`install'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/source/rubygems.rb:205:in
`install'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/installer/gem_installer.rb:54:in
`install'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/installer/gem_installer.rb:16:in
`install_from_spec'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/installer/parallel_installer.rb:132:in
`do_install'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/installer/parallel_installer.rb:123:in
`block in worker_pool'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/worker.rb:62:in
`apply_func'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/worker.rb:57:in
`block in process_queue'
<internal:kernel>:187:in `loop'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/worker.rb:54:in
`process_queue'
D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/bundler-2.5.6/lib/bundler/worker.rb:90:in
`block (2 levels) in create_threads'
An error occurred while installing psych (5.2.0), and Bundler cannot continue.
...
That’s not great! So, I ran into a new problem – one with installing psych
. For some reason, in bundle install
, it fails to build and install psych
but that worked fine when I did a gem update
on the command line, as recommended here for an earlier version.
$gem update
...
Updating psych
Installing required msys2 packages: mingw-w64-ucrt-x86_64-libyaml
Building native extensions. This could take a while...
Successfully installed psych-5.2.0
Parsing documentation for psych-5.2.0
Installing ri documentation for psych-5.2.0
Done installing documentation for psych after 1 seconds
Parsing documentation for psych-5.2.0
Done installing documentation for psych after 0 seconds
...
With that done, I decided to give it a shot again.
$ rails new hello8
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/blog/_posts-trials/rails/hello8/.git/
create app
create app/assets/stylesheets/application.css
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/views/pwa/manifest.json.erb
create app/views/pwa/service-worker.js
create app/assets/images
create app/assets/images/.keep
create app/controllers/concerns/.keep
create app/models/concerns/.keep
create bin
create bin/brakeman
create bin/dev
create bin/rails
create bin/rake
create bin/rubocop
create bin/setup
create bin/thrust
create Dockerfile
create .dockerignore
create bin/docker-entrypoint
create .rubocop.yml
create .github/workflows
create .github/workflows/ci.yml
create .github/dependabot.yml
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_8_0.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 log
create log/.keep
create public
create public/400.html
create public/404.html
create public/406-unsupported-browser.html
create public/422.html
create public/500.html
create public/icon.png
create public/icon.svg
create public/robots.txt
create script
create script/.keep
create tmp
create tmp/.keep
create tmp/pids
create tmp/pids/.keep
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/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_8_0.rb
run bundle install --quiet
WARN: Unresolved or ambiguous specs during Gem::Specification.reset:
stringio (>= 0)
Available/installed versions of this gem:
- 3.1.2
- 3.1.0
WARN: Clearing out unresolved specs. Try 'gem cleanup <gem>'
Please report a bug if this causes problems.
run bundle lock --add-platform=x86_64-linux
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Writing lockfile to D:/projects/blog/_posts-trials/rails/hello8/Gemfile.lock
run bundle binstubs bundler
rails importmap:install
apply D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/importmap-rails-2.0.3/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
Configure importmap paths in config/importmap.rb
create config/importmap.rb
Copying binstub
create bin/importmap
run bundle install --quiet
rails turbo:install stimulus:install
apply D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/turbo-rails-2.0.11/lib/install/turbo_with_importmap.rb
Import Turbo
append app/javascript/application.js
Pin Turbo
append config/importmap.rb
run bundle install --quiet
apply D:/Ruby33-x64/lib/ruby/gems/3.3.0/gems/stimulus-rails-1.3.4/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"
append config/importmap.rb
Appending: pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
append config/importmap.rb
Pin all controllers
Appending: pin_all_from "app/javascript/controllers", under: "controllers"
append config/importmap.rb
run bundle install --quiet
run bundle binstubs kamal
run bundle exec kamal init
Created configuration file in config/deploy.yml
Created .kamal/secrets file
Created sample hooks in .kamal/hooks
force .kamal/secrets
force config/deploy.yml
rails solid_cache:install solid_queue:install solid_cable:install
create config/cache.yml
create db/cache_schema.rb
gsub config/environments/production.rb
create config/queue.yml
create config/recurring.yml
create db/queue_schema.rb
create bin/jobs
gsub config/environments/production.rb
create db/cable_schema.rb
force config/cable.yml
This is a lot better – and it seems fine. This is where we see the one warning and comment. I will try this later after we see if things seem to be working.
WARN: Unresolved or ambiguous specs during Gem::Specification.reset:
stringio (>= 0)
Available/installed versions of this gem:
- 3.1.2
- 3.1.0
WARN: Clearing out unresolved specs. Try 'gem cleanup <gem>'
Please report a bug if this causes problems.
Now, move into that folder (hello8
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
After this, you should be able to go to http://localhost:3000
and see the page below.
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
Let’s add the route get "/articles", to: "articles#index"
into config/routes.rb
as recommended in the tutorial
Now we go ahead and create the controller.
$ 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 also update the template in app/views/articles/index.html.erb
and go to http://localhost:3000/articles and we are now greeted with this:
Next, we add the model.
$ ruby bin\rails generate model Article title:string body:text
invoke active_record
create db/migrate/20241116095243_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
== 20241116095243 CreateArticles: migrating ===================================
-- create_table(:articles)
-> 0.0050s
== 20241116095243 CreateArticles: migrated (0.0058s) ==========================
Also, we add two articles using rails/console
:
hello8(dev)> article = Article.new(title: "Hello Rails", body: "I am on Rails!")
=> #<Article:0x0000022cd5cce418 id: nil, title: "Hello Rails", body: "I am on Rails!", created_at: nil, updated_at: nil>
hello8(dev)> article.save
hello8(dev)> article = Article.new(title: "Hello Ruby 3", body: "New Ruby brings more")
TRANSACTION (0.3ms) BEGIN immediate TRANSACTION /*application='Hello8'*/
Article Create (3.0ms) INSERT INTO "articles" ("title", "body", "created_at", "updated_at") VALUES ('Hello Rails', 'I am on Rails!', '2024-11-16 09:55:06.458798', '2024-11-16 09:55:06.458798') RETURNING "id" /*application='Hello8'*/
TRANSACTION (12.5ms) COMMIT TRANSACTION /*application='Hello8'*/
=> #<Article:0x0000022cd7131900 id: nil, title: "Hello Ruby 3", body: "New Ruby brings more", created_at: nil, updated_at: nil>
hello8(dev)> article.save
TRANSACTION (0.1ms) BEGIN immediate TRANSACTION /*application='Hello8'*/
Article Create (0.5ms) INSERT INTO "articles" ("title", "body", "created_at", "updated_at") VALUES ('Hello Ruby 3', 'New Ruby brings more', '2024-11-16 09:55:22.801409', '2024-11-16 09:55:22.801409') RETURNING "id" /*application='Hello8'*/
TRANSACTION (0.1ms) COMMIT TRANSACTION /*application='Hello8'*/
=> true
Now, as recommended, update the view template and the controller code. 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. Just remember that once you are running within your project, you need to do ruby bin\rails
wherever other tutorials ask you to do bin\rails
normally.