Rails 7: the little big things

The first ever version of Rails I ran into as a bootcamp newbie was rails 6.0.3 so I had missed the webpacker rails 5.x fun times, or lack of them if you talk to older rails developers. Hours spent going down yaml config file wormholes, less than verbose error messages, or ones that just didn’t make sense at all. The asset pipeline there be dragons 🐉, it is yet another piece of the Rails magic that we take for granted / or just don’t really want to go wondering into the woods for, everything is just fine here at the picnic table thanks 🍺 🧺.

Big Things 🐘

webpacker benched, import maps subbed in at the start of the 3rd

The big news has webpacker being officially retired, having played a central role for 5 + years in transpiling and bundling all things js. Technology improvements in http and more importantly http/2 allowed for the advent of esbuild & import maps. Don’t take it from me, take it from D.H.H, the following is now true:

But I like to get my javascript bundling on, old skoolz.. ?

Rails is a large tent, and so are the ways to handle js inside different apps, currently Rails is supporting the following front-end gems:

You can also move away from these defaults for bundling and use either Vite Ruby, or I have previously used Parcel 2 on a Rails 7 with React mock up, my example repo here. This bundles up both of below libraries via the asset pipeline:

As you can see from above, the Rails framework gives an amazing base to work up your project from, no matter what tooling you want / need for your front-end requirements.

Littler Things 🐈

Encrypted Database Layer

You do need to be running Rails credentials from Rails 6.x, but once you have that up and running it gets pretty easy from there and you can just add below to your model.rb:

class Article < ApplicationRecord
  encrypts :title
end

Asynchronous Querying

When you query data, you can now use the load_async method to retrieve results in the background. This is particularly useful if you need to load several unrelated queries from a controller action.

def PostsController
  def index
    @posts = Post.load_async
    @categories = Category.load_async
  end
end

If both queries are fired simultaneously, the total time spent fetching the data will be ~200ms instead of 400ms if they’re executed sequentially.

Tiny Things 🐭

Lazy Load Images

That’s right default lazy images out of the box, just put the flag into the img_tag

 <%= img_tag( @user.avatar, loading="lazy" ) %>

Redirect Back or To

No fallback now required:

  # redirect_back fallback_location: @post

  redirect_back_or_to @post

Tag Attributes From Hash

Transform hash of attributes into ERB tag attributes.

  <div <%= tag.attributes({ id: 'percent-loaded', role: 'progressbar', aria: { valuenow: '75' }}) %>>

Will give the magic pudding of:

  <div id="percent-loaded" role="progressbar" aria-valuenow="75">

Invert a where Clause

Useful way to obtain the inverse of a where call

  good_cats = Cat.where(fun_score: 80..100)
# SELECT \"cats\".* FROM \"cats\" WHERE \"cats\".\"fun_score\" BETWEEN 80 AND 100

  bad_cats = good_cats.invert_where
# SELECT \"cats\".* FROM \"cats\" WHERE NOT (\"cats\".\"fun_score\" BETWEEN 80 AND 100)

I hope that gives you a high level fly by of what’s there to be unpacked from Rails 7.x, there are plenty more hidden gems to find, try the articles below for more.

references:

👉 Next: Product Design Sprints 👈 Previous: Rails Zeitwerk: auto-load your twerk