Issue #8 - 29 August - 4 September 2022

The one with pattern matching

Hello,

I’m Lucian (@lucianghinda on Twitter), and I am the curator of this newsletter.

πŸš€ Code Summaries: Last week, I launched a new section on the newsletter website called Code Summaries. The purpose is to summarise technical articles with Ruby code. I started with the idea that most of the time, I first want to see the code and then read an explanation. That section is not sent via email as I plan to publish it several times weekly. But you can subscribe to it if you want; here is how.

This edition was created with support from @adrianthedev from Avo for Ruby on Rails (a friendly full-featured Rails admin panel) and from @jcsrb, who sent me recommendations to include in the newsletter.

If you have any feedback or ideas about this newsletter, please reach out on Twitter or via email at [email protected]

πŸ‘‰ Emmanuel Hayford shared a tip about how to use Kernel method:

Kernel#__callee__ is cool. It can help you DRY your code. Among other things, you can also use it to inspect methods to see if they have args and if so, what kind. The applications are countless but let's take a look at a DRYing up example.

πŸ‘‰ Petrik De Heus shared a performance benchmark for running simultaneous connections in Ruby 3.2 thanks to work done by @_k01

Looks like running a lot simultaneous connections will be a lot more performant in Ruby 3.2 thanks to @_ko1

See the benchmarks here on Github

πŸ‘‰ Nicolas Alpi πŸͺ shared their experience with deploying a Ruby on Rails app on various PaaS providers:

I've spent the weekend trying out possible Heroku replacements for two different Rails use case - Amba production app where we would be looking to scale and offer web servers and database connections closer to our US and UK customers. - Looking at deploying a small pet app

Here are some main things to consider, but please read the entire thread on Twitter (or via TheReaderApp):

Heroku: β€œWill not be able to achieve multi-region”

Render:

  1. Configuring render.yaml can require some time. More focus on deploying infrastructure and not an app

  2. Price is more flexible than Heroku

  3. Works great, documentation is very good once you understand the concept of infrastructure as code

  4. Multi-region: similar with Heroku, the way to do this is to deploy region based apps

Fly:

  • Region works great

  • Encountered various errors from jmalloc to Ruby version

  • They seem a bit behind answering community questions

Railway

  • Pricing based on usage

  • Simple to deploy

Hatchbokio:

  • "For medium size apps (2 web, 1 worker, 1 db, 1 redis) it can quickly lead to similar(ish) cost than Heroku but with bigger servers"

  • Simple deployment and works out of the box

  • You manage the actual servers, "These are not managed servers, you will be in charge of them"

πŸ‘‰ Nejdet Kadir shared an example about how to dry-rb to validate params:

You can use some @dry_rb gems for validating your parameters. Then you can customize or create some rules, types or more...

πŸ‘‰ Joel Drapper shared new benchmarks for Phlex:

Our internal benchmark results are in the PR description. In a different benchmark, we’re now 2.5Γ— faster than @ViewComponent, over 5Γ— faster than Rails partials and over 37Γ— faster than @dry_rb.Our internal benchmark results are in the PR description. In a different benchmark, we’re now 2.5Γ— faster than @ViewComponent, over 5Γ— faster than Rails partials and over 37Γ— faster than @dry_rb.

πŸ‘‰ Emmanuel Hayford shared a piece of code about how to restrict a method to accept keyword args:

Did you know that in Ruby you can explicitly instruct a method not to take keyword arguments? Otherwise the method sucks up the keywords in the rest argument.

πŸ‘‰ Facundo Espinosa shared a code example about using |= operator:

I just discovered the |= operator in #ruby

πŸ‘‰ A question asked by Facundo Espinosa about what do you use for Admins today in Rails, triggered an excellent answer by Adrian Marin from www.avo.cool about what DSLs are:

And he then goes to balance between writing Rails code and making abstractions:

I know what you mean. "It's something new that the team must learn in order to use it.". The alternative usually is "If it's regular Rails code it's easier. Everyone knows Rails!". I say that that's a fallacy and most of the time false. πŸ‘‡ @mentions All that "Rails code" is actually custom code written inside Rails. But it's not all the same and equal. Yes, sometimes it's just permitting params and passing them to the model, but most of the time it's not that but a series of abstractions. @mentions Most of the times, the only person that appreciates that code is the author. The one that made it and thinks in those paradigms. All the new team members will come in and have to learn what the author meant with their abstractions, why they did it, and why they work that way. @mentions Those abstractions become a DSL in themselves. Using something like Avo is just the next level over other libraries. @mentions You could say the same thing (a DSL is costly) about devise, pundit, inline_svg, webpacker, acts_as_list, rspec, and others. They all have DSLs that take time to learn and master. But you stick with them because the gains outweigh the costs.

πŸ‘‰ Nate Berkopec shared advice about how to use Puma and triggered and discussion about how to design the app to call external services:

It is worth reading the thread as is has some interesting takes:

In case you still want Puma with threads, Nate shared in 2021 a good thread about a basic configuration. You should read that Twitter thread as it has more recommendations for various configurations. Here are the main points:

In a production environment, the optimal Puma configuration for 80% of apps is probably 4 workers, 5 threads on a 4vCPU machine with ~8GB of memory.
8GB for 4 workers is probably more memory overhead then you're ever gonna need but that 1vcpu:2GB ratio is the lowest that most cloud vendors sell so lower memory usage doesn't get you much.

πŸ‘‰ Andrew Mason shared how to use Pry to show source location for methods:

Did you know you can use pry to quickly show the location of a method you are using or trying to find? You can pass it a few different things: `show-method Post.first.slug` `show-method Post#slug` And it will display the method in your console! Bonus: check out `show-source`

If you are not using Pry, the source location is included in Ruby.

πŸ‘‰ A frustration shared by Benoit Daloze about the defaults of Rubocop, triggered a long discussion with some examples of defaults for cops not working well for some people.

As a result of this Joel Drapper shared they are starting a new project to set up sane Rubocop defaults. The work has not yet started, but he already created a repo for it here at joeldrapper/good_cop

This annoys me so much. Rubcop defaults to β€œbad cop” mode. But you can easily configure it to inherit from a url so I just registered https://t.co/tLRBOjAdF0 to host a Rubocop configuration for people who write beautiful Ruby.

πŸ‘‰ Facundo Espinosa shared a short TIL about reorder in active record:

TIL the `reorder` method in ActiveRecord #rails #ruby

πŸ‘‰ Ruby Conf Mini shared an announcement about an opportunity scholarship for RubyConfMini. You can directly apply here if you want. Deadline 17 September.

πŸ‘‰ Nate Berkopec shared a proposal about how to name queues: by using their SLAs:

I feel more strongly than ever that background job queues should be named after their SLA (i.e. "within_1_minute"). Without making that SLA in-your-face explicit, there is no SLA and customer experience suffers.

For more insights, you can read this article about how they do this at Gusto.

πŸ‘‰ Julian Rubisch shared a sample code to feature flag a route in Rails when using Devise:

A quick one: Here's how to restrict a Rails route with a flipper feature flag via route constraint (assuming Devise)

πŸ‘‰ Steve Polito shared advice with a code sample for testing error messages:

If you’re writing tests for a model validation in #rails, consider testing the error message to ensure the correct validation is being tested to avoid false positives. Alternatively, write a system test that ensures the correct message is displayed when the form is submitted.

Code sample:

# ❌ the record may be invalid for a different reason. it "is invalid" do freeze_time clinic=build(:clinic, app_active: false) appointment=build( :appointment, type: Appointment::IN_CLINIC_TYPES.first, clinic: clinic, starts_at: Time. current ) expect(appointment).to be_invalid end # This ensures the correct validation is being tested. it "is invalid" do freeze_time clinic=build(:clinic, app_active: false) appointment=build( :appointment, type: Appointment::IN_CLINIC_TYPES.first, clinic: clinic, starts_at: Time. current ) appointment.validate expect(appointment.errors. full_messages).to match_array(["Clinic location is not currently supported."]) end

πŸ‘‰ Jason Swett shared an experiment to organise tests by feature and not by test type:

Some months ago I decided to organize my tests by feature instead of by test type. Having lived with it for a while now, I would never go back.

The main benefit is:

I can run ALL the tests for a feature or area in one command because they're all grouped in one folder - great for when I want to check for regressions without having to run the entire test suite

Here is how he explains the structure of the test folder:

πŸ‘‰ Drew Bragg shared an old code example about reading __END__ data in multi-file view component:

But there are more ideas about how to do this in this thread started by Konnor Rogers

πŸ‘‰ Thiago Massa shared that merging hash with splat operator is faster (source) than using merge:

Almost all Ruby developers I know use the Hash#merge method to append one Hash to another. What if I told you, you could do this using the double splat operator(+coolness factor) and it is sightly faster?

He also shared a code sample about how to use pattern matching:

And here is another example shared by Thiago Massa :

And here is an example shared by me where I mix pattern matching with static typing checking and omitting values in keyword arguments:

πŸ‘‰ abuisman shared on Reddit how to rotate credentials key without downtime:

If you read so far and you like the content, maybe you take into consideration sharing this and subscribe:

Related (but not Ruby specific)

Josef Strzibny shared a concise image explaining positioning for CSS grid layout:

Koichi Ito shared shared 3 frames in time when a developer is doing a review of their work:

There are three timings for code self-review. 1. git log -p before git push 2. Diff in browser before opening PR 3. Diff in browser just after opening PR I was talking about something like that yesterday at 1on1. Especially 1 is done many times during development.

Vim Tricks shared tip about how to change case in VIM:

Change the case of characters with ~, u, and U. Some examples: β€’ gUw – Uppercase to end of word β€’ gUiw – Uppercase entire word β€’ guap – Lowercase paragraph

Jared White shared a new project about converting Tailwind CSS to Semantic CSS: vanillabreeze.dev:

Introducing Vanilla Breeze. https://t.co/wir2jTlwwZ Convert Tailwind CSS to Semantic CSS. Why would anyone want to do that?! I’ll be unpacking that in detail in the weeks ahead. First post in the series here: https://t.co/5VOatmbd8Y It’s open source so issues and PRs welcome!

He wrote a good article explaining how to use utility classes in a maintainable way: The Three Laws of Utility Classes. It is worth reading!

Tobias Petry.Sql shared shared a new SQL tip about how to fill in data gaps automatically in SQL:

Mike Perham shared a good and short insight into marketing:

The best product marketing is "show people what you built and explain how it might benefit them". That's it. "Benefit" is a spectrum from "solves my immediate need" to "utter spam"

Thiago Massa shared nice trick to transpile JS in browser:

TIL: By using babel's unpkg and a script tag with "text/babel" with the code you want to be transpiled, you can easily run transpiled JS in the browser. I used to use codepen because I wasn't aware it is that easy. Don't use this for production purposes though.

Gee Paw Hill shared an excellent thread about how we think, and this tweet is an excellent summary of what makes change hard:

Articles and Videos

Courses or Books

Justin shared launched a new Ruby On Rails course: Modern Application Development with Rails

Something to read

Newsletters

πŸ—ž VimTricks released a new edition of their newsletter about Vim here: Vim Search Visual Selection

πŸ—ž Greg Molnar shared they published the latest issue of This week in rails

πŸ—ž David shared a new newsletter with interesting things found on Twitter: Weekly bookmarks - Issue #17

πŸ—ž Ruby LibHunt released their 328 issue of Awesome Ruby Newsletter. 

πŸ—ž Ruby Weekly released their 618 issue

πŸ—ž Ruby Radar shared they released their 65 issues: #65 - Fly Away From Heroku

Articles

Tom Doe shared an article about Ruby loops overview.

The Ruby Dev shared how to set up Git to run static analysis on Ruby/Rails: Read the article here

Tute Costa shared an article about value objects in Ruby, written by JoΓ«l Quenneville: Value Object Semantics in Ruby

Justin Searls shared a new article they wrote about using custom attributes types in Rails and how to use them with forms: Stateless Forms with the Rails Attributes API

Ruby Lib Hunt shared an article about how to write code and think about the principle of least surprise: Keep it boring, don’t surprise me

Something to watch or listen

Videos

πŸŽ₯ Drifting Ruby shared a new episode they published about learning Hotwire: this one they build a Full Calendar for an appointment scheduling program. See it here β†’ Episode 364 - Booking System

πŸŽ₯ Hanami Mastery shared a new article about using Sidekiq with Hanami: See it here β†’ Integrate Sidekiq with Hanami Applications

πŸŽ₯ Timnan shared a new tutorial about implementing TimetableJS in Ruby on Rails: See it here β†’ Implementing TimetableJs in Ruby On Rails

πŸŽ₯ Facundo Espinosa shared an older tutorial done by Mario Visic about building asteroids game with ruby2d: See it here β†’ Building a player select screen - Asteroids Ruby 2D Part 1

πŸŽ₯ Rubyland shared a collection of RailsConf talks by Shopify engineers. See them here β†’ RailsConf 2022: 10 Shopify Tech Talks You Might Have Missed

πŸŽ₯ Cj Avilla shared a video released by GoRails about how to deploy to Fly. See it here β†’ How to Deploy Rails to Fly.io

πŸŽ₯ Drifting Ruby shared the video format of the This week in Rails newsletter: See it here β†’ This Week in Rails Sept 2nd, 2022

πŸŽ₯ The Rubber Duck Dev Show shared a new episode this time with Drew Bragg. See it here β†’ Episode 57 | Going Off The Rails With Drew Bragg

Audio & Podcasts

🎧 Stephan Hagemann shared a great discussion about modularization and internationalization with Irina Nazarova - CEO @evilmartians. Listen to the recording here β†’ Ruby@Scale

🎧 Jason Swett shared their latest episode from Code with Jason where he talks with Andrew Atkinson about PostgreSQL. Listen to it here β†’ 160 - PostgreSQL with Andrew Atkinson

🎧 JoΓ«l Quenneville shared a new episode of The Bike Shed about submitting talks to conferences, case expressions, and good enough. Listen here β†’ The Bike Shed: 352: Case Expressions

🎧 Therubyonrailspodcast shared a new episode where they talk about layoffs. Listen here β†’ Episode 433: The One About Layoffs (Brittany + Brian)

🎧 Ruby For All shared a new episode about pairing with Josh Goldberg. Listen here β†’ Pairing with Josh Goldberg

Gems, Libraries, and Updates

🧰 Avo shared a new release of their Admin for Rails library. This has a lot of improvements: select all matching records, override destructive actions, automatic required option, and more. Check the changelog here

🧰 Aaron Patterson shared a new database adapter for Ruby on Rails called Trilogy:

Compared to the mysql2 gem, Trilogy avoids a dependency on the libmariadb / libmysqlclient library, which can simplify gem installation and eliminate version mismatch issues, and minimizes the number of times data must be copied in memory when building and parsing network packets. It should simplify gem installation and be more efficient under heavy query loads.

Check the gem here, it is compatible with the main branch of rails

🧰 Marco Roth shared shared they are working on a new gem providing more power to interact with DOM from Ruby. See the gem here: marcoroth/turbo_power-rails. It adds some very cool actions from DOM actions, Attribute Actions, Event Actions, Storage Actions, Browser Actions, Browser History Actions and more.

Here are just some examples, but there are many more on the Github homepage:

🧰 Pascal LalibertΓ© shared shared a bit of work done for creating a charts library for Rails. Check the website here.

🧰 Sam Aaron πŸ‡ͺπŸ‡Ί πŸ‡ΊπŸ‡¦ shared a new release of Sonic Pi that supports nudging time forward or back to sync the phase with an external rhythm. Read here more about this release.

🧰 Mike Dalessio shared new version of sqlite3 gem. This is v1.5.0.rc2. See the initial release notes of v1.5.0 here

🧰 Sam Ruby shared announced a change to flyctl to allow deployment of Rails via fly.rake. See the RFC: have fly launch produce a lib/tasks/fly.rake. Here is what it might look like:

🧰 Bozhidar Batsov (Bug) πŸ‡§πŸ‡¬πŸ‡ͺπŸ‡ΊπŸ‡ΊπŸ‡¦ shared a new release of Rubocop containing small improvements. RuboCop 1.36

🧰 Jeremy Evans shared a new release of Sequel 5.6.0. See change log here

🧰 Eric Berry πŸ’œ πŸ‡ΊπŸ‡¦ shared a gem created by Igor Kasyanchuk about printing debugging information called Wrapped print.

🧰 Konnor Rogers shared a gist for having a single file view component. Check it out here

This was a long issue as there was a lot of great content that I discovered in Ruby community. I started to follow what is happening on Reddit communities so I will probably start bringing content from there.

Please consider sharing this on social media or with your colleagues:

Reply

or to participate.