Short Ruby Newsletter - edition 110

Stay updated on Ruby with launches like Ruby Static Pro, events like RubyConf, and the first RC of Rails 8.0.0. Explore new Ruby gems, tools, and insightful code samples in our latest newsletter.

In partnership with

Table of Contents

(Partnership)

πŸ“’ A rather rare job opportunity popped up at Avo. If you have the skills and think this will challenge you to grow, send in your resume.  Avo, the custom Admin Panel Framework, Content Management System, and Internal Tool Builder for Ruby on Rails, is looking to hire a mid-level Ruby on Rails Developer.

Source: avohq.io

πŸš€ Launches and discounts

πŸš€ Donn Felker launched Ruby Static Pro - Welcome - a Ruby static site generator template based on Middleman:

Source: @donnfelker

πŸš€ Trae Robrock (re)launched Translated

Source: @trobrock

πŸ“… Events

πŸ“… Alex Rudall announced a workshop by Obie Fernandez about Ruby AI Show n Tell happening on 22 October:

Source: @alexrudall

πŸ“… Honeybadger.Io announced a workshop together with Wafris on 24 October about Errors n’ Incidents

πŸ“… Thoughtbot announced Open Summit Hack on 25 October:

Source: @thoughtbot

πŸ“… Lukasz Reszke announced a workshop by Arkency about 10 Arkency Lessons from Rails apps for 2025 happening on 30 October:

πŸ“… Ruby Conf announced there is still time to book a room until October 25 for the RubyConf:

Source: @rubyconf

Ad

Codeium - the AI Coding Assistant for Enterprise Development Teams

  • Accelerate time to delivery to outpace your competition

  • Promote technical excellence to scale your development team

  • Mitigate operational risk in your AI strategy

πŸ‘‰ All about Code and Ruby

πŸ‘‰ David Heinemeier Hansson announcing Rails 8.0.0.rc1 release. See release notes here

Source: @dhh

and Lex Fridman replying with:

Source: @lexfridman

πŸ‘‹ Please take a few seconds to reflect if you want to upgrade your newsletter subscription to a paid version. You will enjoy an ad-free edition and support the newsletter for as low as 8$ per month. Here are more reasons why I think you should upgrade to paid.

πŸ’» Code Samples

οΈπŸ’» Jason Nochlin shared a code sample showing how to use Kamal 2 with its own private registry: Host Your Own Docker Registry with Kamal 2

οΈπŸ’» Nate Berkopec shared about common cache mistake in Rails views:

οΈπŸ’» Mohit Sindhwani shared a code sample (see the article Ruby Tips 14 - Copy a file with a new base name)

Source: @onghu

# Source: https://notepad.onghu.com/2024/ruby-tips-014-save-file-with-new-name/

  def save_old_file (file)
    # nothing to do if the file is not there
    return unless File.exist?(file)

    # suffix has the date and time in it
    suffix = DateTime.now.strftime("p%Y%m%d-%H%M%S")

    dir = File.dirname(file)
    ext = File.extname(file)

    # Get the base name without the extension
    base_name_without_ext = File.basename(file, ext)

    # Constitute the new name using the base name, the suffix, and the extension
    new_name = "#{base_name_without_ext}-#{suffix}#{ext}"

    # Create the full path
    new_file_path = File.join(dir, new_name)

    # Copy the original file to the new path
    puts "Backing up: #{file} -> #{new_file_path}."
    FileUtils.cp(file, new_file_path)
  end

οΈπŸ’» Alex Rudall shared a code sample showing how to use OpenAI Rag with ruby-openai: OpenAI API + Ruby!

Source: @alexrudall

require "openai"

# Make a client
client = OpenAI::Client.new(
  access_token: "access_token_goes_here",
  log_errors: true # Don't log errors in production.
)

# Upload image as a file
file_id = client.files.upload(
  parameters: {
    file: "path/to/example.png",
    purpose: "assistants",
  }
)["id"]

# Create assistant (You could also use an existing one here)
assistant_id = client.assistants.create(
  parameters: {
    model: "gpt-4o",
    name: "Image reader",
    instructions: "You are an image describer. You describe the contents of images.",
  }
)["id"]

# Create thread
thread_id = client.threads.create["id"]

# Add image in message
client.messages.create(
  thread_id: thread_id,
  parameters: {
    role: "user", # Required for manually created messages
    content: [
      {
        "type": "text",
        "text": "What's in this image?"
      },
      {
        "type": "image_file",
        "image_file": { "file_id": file_id }
      }
    ]
  }
)

# Run thread
run_id = client.runs.create(
  thread_id: thread_id,
  parameters: { assistant_id: assistant_id }
)["id"]

# Wait until run in complete
status = nil
until status == "completed" do
  sleep(0.1)
  status = client.runs.retrieve(id: run_id, thread_id: thread_id)['status']
end

# Get the response
messages = client.messages.list(thread_id: thread_id, parameters: { order: 'asc' })
messages.dig("data", -1, "content", 0, "text", "value")
=> "The image contains a placeholder graphic with a tilted, stylized representation of a postage stamp in the top part, which includes an abstract landscape with hills and a sun. Below the stamp, in the middle of the image, there is italicized text in a light golden color that reads, \"This is just an example.\" The background is a light pastel shade, and a yellow border frames the entire image."

οΈπŸ’» Chris Oliver shared that Rails is looking for a specific DATABASE URL for each environment #{name.upcase}_DATABASE_URL:

Source: @excid3

οΈπŸ’» Ruby Cademy shared a thread with 5 Rails shorthands. I am including here two of them but you should read the entire thread on Twitter or on Threadreader app:

Source: @RubyCademy

Source: @RubyCademy

οΈπŸ’» Greg Molnar shared a thread about TailwindCSS and Rails 8 | Greg Molnar

Source: @GregMolnar

Read the entire thread via Threadreader or via the article he wrote.

οΈπŸ’» Ross Kaffenberger shared a code sample about markdown rendering (read the entire thread in Threadreader)

Source: @rossta

# Source: https://x.com/rossta/status/1847301146404168169/photo/1

️require "commonmarker"

def visit (node)
  return if node.nil?

  case node.type
  in :document
    visit_children (node)
  in :heading
    header(node.header_level) { visit_children (node) }
  in :paragraph
    p { visit_children (node) }
    # ...
  end
end

def visit_children(node) 
  node.each { |c| visit (c) }
end

visit (Commonmarker.parse("# Hello World\n\nHappy Friday!"))

οΈπŸ’» Ruby Cademy shared a code sample showing how to use the Data object:

Source: @RubyCademy

οΈπŸ’» Bhumi reminded us about what === does in Ruby:

Source: @bhumi1102

>> String === "hello"
=> true

>> "hello". is_a?(String)
=>true 

>> String === :hello
=> false

>>(1..10οΌ‰=== 5
=> true

>> (1..10).include?(5)
=> true

>> (1..10) === 42

=> false

# Source https://twitter.com/bhumi1102/status/1846207979638473116

πŸ’» Zach Gollwitzer shared a short video showing how to use the debug gem with VScode (see the video on Threadreader)

Source: @zg_dev

οΈπŸ’» Haseeb Annadamban shared useful shortcuts in Rails Console:

Source: @Haseebeqx

οΈπŸ’» Takeshi Komiya shared a demo of how RBS::Inline works. You should also read this article where they go over how to install and use RBS::Inline: I tried installing RBS::Inline (1) - EN translated with Google

Source: @tk0miya

οΈπŸ’» Ahmed Nadar shared a code sample from their project RapidRails UI Components showing a Stimulus controller for link, avatar and preview:

Source: @ahmednadar

// Source: https://x.com/ahmednadar/status/1847625337191924117

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["preview"]
  static values = { duration: { type: Number, default: 700 } }

  connect() {
    if (this.hasPreviewTarget) {
      this.previewTarget.classList.add('transition-all', `duration-${this.durationValue}`, 'ease-in-out', 'delay-300')
    }
  }

  show() {
    if (this.hasPreviewTarget) {
      this.previewTarget.classList.remove('opacity-0', 'hidden')
      this.previewTarget.classList.add('opacity-100', 'active')
    }
  }

  hide() {
    if (this.hasPreviewTarget) {
      this.previewTarget.classList.remove('opacity-100', 'active')
      this.previewTarget.classList.add('opacity-0')

      setTimeout(() => {
        this.previewTarget.classList.add('hidden')
      }, this.durationValue)
    }
  }
}

οΈπŸ’» Peter Solnica shared a code sample from Sidekiq:

Source: @solnic29a

πŸ’» Zhephyn shared a thread about about introduction in building with Hotwire (read the entire thread on Threadreader app):

Source: @zhephyn

οΈπŸ’» Jack Sebben shared their learnings so far about Rack (read the entire thread on Threadreader). Here is the first part of their long post:

πŸ“ Thinking a bout Code Design

οΈπŸ“ Josef Strzibny shared about kamal redeploy speeding up frequent deployments:

Source: @strzibnyj

οΈπŸ’» Guillaume reminded us about Docker bypassing UFW rules (see also How to deploy Rails with Kamal, PostgreSQL, Sidekiq and Backups on a single host)

οΈπŸ“ Joel Drapper doing a short demo about sever-sent-events with Yippee:

Source: @joeldrapper

οΈπŸ“ Vitaly Slobodin shared that Gitlab billing system relies heavly on VCR for testing:

Source: @Vitalliumm

Julia added:

Source: @yukideluxe

οΈπŸ“ Joel Drapper shared about SQLite:

Source: @joeldrapper

οΈπŸ“ Nate Berkopec shared about starting a new Rails app and hosting it in EU:

πŸ“ Matt Swanson did an interesting and open exercise sharing some code and asking to be roasted:

Source: @_swanson

Source: @kaspth

οΈπŸ“ Daniel Hoelzgen asked about Sidekiq vs GoodJob vs Solid Queue:

Source: @dhoelzgen

A couple of reources where shared:

And here are some other replies:

Source: @robzolkos

Source: @julikt

Source: @lfv89

οΈοΈοΈπŸ“ Nate Hopkins shared about using Minitest assert_pattern method:

Source: @hopsoft

οΈοΈπŸ“ Nate Berkopec shared about boot time:

οΈπŸ“ Greg Molnar shared about the advantages of using ActiveJob as it allows easily migrating between background processing queues:

Source: @GregMolnar

πŸ’‘Around code (news, findings, books, and more - all about Ruby)

πŸ’‘ Jeremy Evans shared roda passed 10 million downloads:

οΈπŸ’‘ Samuel Williams shared installation stats about rack 3:

Source: @ioquatix

πŸ’‘ Joe Masilotti shared about their Hotwire Native community on Discord:

πŸ’‘ Ruby Europe shared about their second pillar for building a Ruby Europe:

Source: @RubyEurope

❀️ Why Choose Ruby and Rails

❀️ Avi Flombaum shared about Rails:

Source: @aviflombaum

❀️ Vojtech Rinik shared how they started with Rails:

Source: @_vojto

❀️ Siddharth shared about Rails ecosystem:

❀️ Stephen Margheim shared about Rails 8 providing a production-ready SQLite experience:

🧰 Gems, Libraries, Tools and Updates

πŸ†• New Gems and Repos

Source: @rorvswild

🧰 Updates

🧰 Samuel Williams announced a new version of rack/CHANGELOG.md at main Β· rack/rack

Source: @ioquatix

🧰 Bozhidar Batsov announced a new release of Release RuboCop 1.67 Β· rubocop/rubocop with a lot of bug fixes and changes. Here is just the part of the release notes about new linters/cops:

Source: rubocop

🧰 Mike Dalessio announced a new version of Release v3.0.0 Β· rails/tailwindcss-rails

Source: @flavorjones

Source: @bradgessler

🧰 Jet Brains Ruby Mine announced a new version of RubyMine 2024.3 EAP 5:

Source: @rubymine

🧰 Samuel Williams announced that Arch Linux Ruby is now updated to Ruby 3.3.5:

Source: @ioquatix

🧰 Obie Fernandez announced a new version of GitHub - OlympiaAI/raix: Ruby AI eXtensions

Source: @obie

Source: @hschnedlitz

🧰 Marc Anguera announced the release candidate for sidekiq-cron - Scheduler / Cron for Sidekiq jobs

🀝 Nate Berkopec shared abbout performance goals:

🀝 Akinori Musha shared about HTTP Date and If-Modified-Since header:

Source: @knu

🀝 Kyri shared shared about protecting a VPS:

Source: @kkyrio

🀝 Simon Chiu shared a long post (here I included only the first part) about lessons learned from launching their project.

Source: @geetfun

More content: πŸ“š πŸ—ž 🎧 πŸŽ₯ ✍🏾

πŸ—ž Newsletters

πŸ—ž Irene Kannyo published a new edition of Ruby Central Newsletter about October 2024 Newsletter

πŸ—ž Ruby Libhunt published a new edition about Issue 439 - Cleaning up Ruby code with Railway Oriented Programming

πŸ—ž Sajjad Umar published a new edition about Ruby on Rails - Oct 2024

🎧 Podcasts

🎧 Chris Oliver published a new podcast about DHH on Rails World 2024 and what’s coming in Rails 8.1

🎧 Yaroslav Shmarov published a new podcast about Andrew Culver: BulletTrain, ClickFunnels & Family Adventures πŸš€ Live from Rails World 2024!

🎧 Remote Ruby published a new episode about Live at Rails World aka Undercover Duck

🎧 Fullstack Ruby published a new episode about Episode 11: Designing Your API for Their API (Yo Dawg!)

🎧 Thoughtbot published a new podcast about The Bike Shed: 443: Rails World and Open Source with Stefanni Brasil

🎧 Ode To Rails Conf published a new podcast about Erica McDevitt

🎧 Indie Rails published a new podcast about IndieRails | One Person Framework with Justin Searls

🎧 The Bike Shed published a new podcast about 444: From Solutions To Patterns

πŸ“½οΈ πŸŽ₯ Videos

πŸŽ₯ Ruby on Rails announced that all the talks from Rails World 2024 are now online

πŸŽ₯ Drifting Ruby published a new video about Kamal 2 with PostgreSQL | Drifting Ruby

πŸŽ₯Joel Drapper published a new video about Here’s a first look at the Yippee router.

πŸŽ₯ Hanami Mastery published a new video about Last Puzzle in place! Fullstack Hanami 2.2!

πŸŽ₯ Jason Swett published a new video about Getting Nested Parentheses (Almost) Working - Ruby OOP

πŸŽ₯ Jeremy Smith published a new video about Building liminal.forum (link to video on Threadreader)

πŸŽ₯ Ruby Unconf published the videos from the Ruby Unconf conference

πŸŽ₯ VinΓ­cius Alves Oyama published a new video about Create Dynamic Form Fields in Rails with Auto-Updates Using Hotwire, StimulusJS and Turbo

✍🏾 Articles

What’s new πŸ†•

Victor Shepelev published an article about There is no such thing as a global method (in Ruby)

Ruby Central announced they are supporting Open Source Pledge

Avinash Joshi published a new article about Kamal 2: My upgrade journey

Aaron Patterson published an article about Tenderlove Making - Monkey Patch Detection in Ruby

Stephen Margheim published an article about Supercharge the One Person Framework with SQLite. And related to this Simon Willison published an article about Supercharge the One Person Framework with SQLite: Rails World 2024

Andy Croll published a new article about Launching UsingRails: A Directory of Rails-Based Organisations

Younes Serraj published an article about What is Rack?

Martin Emde published a new article about New Design for RubyGems.org

Kasper Timm Hansen published a new article about Code golfing review: how to make composable Active Record queries

Robert Pankowecki published a new article about Technical Key Pattern

Steve Polito published an article about Build a (better) search form in Rails with Active Model

Andrew Atkinson published a new article about Rails World 2024 Conference Recap

Michael Berger and Gabriel Monette published an article about All about QA

Greg Navis published a new article about Rails on OpenBSD: Base System

Max Chernyak published an article about Turbo 8 FAQ - Max's Notes

Prasanth Chaduvula published an article about Rails 7.1 Raises Error On Assignment To Readonly Attributes

Vishnu M published an article about Benchmarking Crunchy Data for latency

Reni Mercier published an article about Interfacing with external APIs: the facade pattern in Ruby

How-TOs πŸ“

Donn Felker published a new article about Ruby Script for Telegram Notifications - DONN FELKER

Mike Rispoli published an article about Format on save for ERB and Ruby files in Zed IDE

Sergio Alvarez published an article about Full-text search with Rails and SQLite

Simon Chiu published an article about Using Thruster web server for Ruby apps

Jason Nochlin published an article about Host Your Own Docker Registry with Kamal 2

Ross Kaffenberger published a new article about Joy of Rails | Mastering Custom Configuration in Rails

Mohit Sindhwani published an article about Ruby Tips 14 - Copy a file with a new base name

BestWeb Ventures published an article about 10 Best AI Tools for Ruby on Rails 8 Development in 2024

Rails Designer published an article about Changing CSS as You Scroll with Stimulus

Reply

or to participate.