How to try rails 8

Hi, I’ve already got rails 7.1.x installed as a gem in a ruby 3.3.x rbenv.

How do I try out rails 8 (on a new project) without overriding the previous 7.x stable gem?

(E.g. install separate gem store? or install from where I can use a FQ path for rails new ...

I’m used to creating a virtual-env in python so project-specific libs go in there, but i can’t see that there is a similar pattern for rbenv or rvm.

Thanks

Rob

Hi @r952, what OS are you using?

In general, you can use gem install rails -v 8.0.0.beta1. or gem install rails --prerelease You can use rbenv to specify which ruby version you want to use for your project, or in general.

Please check:

Thank you @dalibor.os

I’m on MacOS & linux.

In fact I did this as you described but now my rails binary that’s in the PATH set by rbenv is Rails v8

How do I get back to Rails 7 for other projects? Or am I required to … gem install rails -v <version i need right now> and flip-flop around forcing gems to whatever version I need at the time?

Thanks again

R

You can call a specific version of rails by adding the version string after it in the command line, like this: bundle exec rails _7.1.2_ new whatever... (obviously, use a version you have installed, see gem list rails for your local versions. The underscores are actually important in this case, not placeholders for this answer.

Walter

1 Like

This is great, thank you @walterdavis

So it’s bundler that can negotiate the various installed versions. Very useful step-up on the learning curve! Cheers

R

Actually, I think I may have misspoken here: it’s not bundler that does this, and unless you have a Gemfile in the directory where you are running Rails, this may not work, either. Try it without the bundle exec prefix. It’s just a feature of the rails executable itself.

Walter

1 Like

@walterdavis that’s it!

Looks like something called railties knits the desired version with the installed Gem.

rob@quark /tmp % which rails
/Users/rob/.rbenv/shims/rails

rob@quark /tmp % rails -v
Rails 8.0.0.rc1

rob@quark /tmp % gem list ^rails$

*** LOCAL GEMS ***

rails (8.0.0.rc1, 7.2.1.2, 7.1.3.2, 7.1.3)

rob@quark /tmp % rails _7.2.1.2_ -v
Rails 7.2.1.2

rob@quark /tmp % rails _7.2.1.X_ -v
/Users/rob/.rbenv/versions/3.3.0/lib/ruby/3.3.0/rubygems.rb:259:in `find_spec_for_exe': can't find gem railties (= 7.2.1.X) with executable rails (Gem::GemNotFoundException)
	from /Users/rob/.rbenv/versions/3.3.0/lib/ruby/3.3.0/rubygems.rb:278:in `activate_bin_path'
	from /Users/rob/.rbenv/versions/3.3.0/bin/rails:25:in `<main>'

Thanks again

Rob

I’d like to try out Rails 8 for a new project without interfering with my existing setup or overriding the stable 7.x gem. In Python, I’m used to creating virtual environments to isolate project-specific dependencies, but I’m not sure what the equivalent is with rbenv.

@TerryJesse

I don’t think there is a standard equivalent for Python’s virtualenv in ruby environments such as rbenv.

However, it seems rbenv retains multiple versions of gems (unlike py-virtenv which is a list of requirements pertaining to only a single version of each package)

As such, you can keep installing new verisons, and specifying different versions and they all exist in the gem folder locally.

There’s another specific workaround in that … even though “rails” might point to a specific version of this gem, the rails command accepts a version switch so it can load a different version other than itself.

See my CLI examples a coupel of posts up :point_up_2:

Hope this helps

Rbenv (and rvm and asdf and other version managers) maintain a separate set of gems for each version of Ruby. They usually put these in a filesystem tree with a /major.minor/ segment in it. Gem itself is also separately versioned by this same scheme. Think of the version managers as a kind of hypervisor for Ruby and other languages. (Asdf is quite limber, and can version a large number of different languages independently.)

All that aside, when you want to run a particular version of a command-line tool like the ones Rails installs, you have a few options. You can signal which version to use with a n.n.n segment in the command, as in rails _7.0.0_ new .... That will always work, even if you have also installed a higher version of Rails.

You could also only install the newest Rails in the highest Ruby*, so using rbenv, you might first install Ruby 3.3.x, and then while you are in that version of Ruby, install Rails without any version argument, which should get you the latest version of Rails. While you are using Ruby 3.3.x, if you type gem list rails, you should only see the latest version listed. But if you are in Ruby 3.2.x, you might see three other lower versions you installed there and not see the latest.

See of any of these approaches make sense to you.

Walter

*This is also a very good practice to follow, because there are definite limits to how high you can go in Ruby while also running a lower version of Rails successfully. Particularly around upgrade inflection points, there are usually some critical failures possible because the Rails framework was working around older language bugs, or leveraging features in a newer version that are just not there in an older version. There is a matrix of “considered safe” combinations on Ombulabs’ blog.

1 Like

Yes, RVM is the closest to that style in the Ruby world with its concepts of a gemset. That being said, RVM pre-dated Bundler which sort of obsoleted that way of working (which is why rbenv and asdf are much simpler).

I believe in the Python world, requirements.txt is the list of deps but those are installed globally hence the need for something like virtual-env to keep things separate. Bundler will also install deps but it does more than that. It modifies the load path so that only the specified gems (at those specific versions) are used for a project.

This setup allows each project to have it’s own list of gems that are isolated from each other at runtime while not needing to have entirely separate installs of those gems. I.E. the way Python’s virtual-env works is how things used to be before Bundler in RVM but Bundler obsoleted that way of working.

If you want to work with Rails 8 on project A but Rails 7.x on project B then there are no conflicts because both projects will have their own Gemfile which specifies what version is to be added to the load path.