Hey, #ruby folks! I've been one of the #RubyGems maintainers for the last decade.
Ruby Central has forcefully taken control of the RubyGems organization on GitHub, the `rubygems-update` and `bundler` gems on rubygems[.]org, and more.
You can read the details here: pup-e.com/goodbye-ruby...
Posts by Rado Stankov
Here is example usage
Introducing On Rails. A New Podcast.
rubyonrails.org/2025/6/25/on...
I'm now maybe using this 10-20 times a day. I haven't realized how hard was to select UI text, errors and similar on modern Desktops.
cleanshot.com
One of the biggest "AI" powered productivity boosters, started using recently, is CleanShotX Capture text (OCR). I just click CMD+6 pick and area form my screen and get the text there into the clipboard.
I'm seriously impressed with the new ChatGPT image generator. I gave him couple screenshots of sales slides. Asked it to generate icons for couple of features. Then change background and replace $ with € in the icons and result were quite good.
I think is more about the Digital Markets Act, which doesn’t allow vendors to favor themselves. An example is the screen mirroring of the iPhone on the Mac, being disabled in EU.
The best way to avoid database queries is to avoid making them. Counter caches help with that. Active Record built-in counter cache is good but doesn't handle conditions and deltas.
If you want to learn more about counter caches, I have a whole post about them 👉
tips.rstankov.com/p/counter-ca...
After 15 years off the market, I’m available for hire!
I’m an effective, versatile and compassionate technical leader, and an accomplished Rubyist. I’m looking for remote Principal or Staff Engineer roles, at 4 days/week.
Find out more: timriley.info/posts/hire-me
Most habits a junior developer picks up in the early days of their career will stick. Here are my tips for developing good habits as a junior developer. 🤓
tips.rstankov.com/p/tips-for-j...
More GIT aliases 👉
github.com/RStankov/con...
# .gitconfig
[alias]
delete-merged = !git branch --format '%(refname:short) %(upstream:track)' | awk '$2 == \"[gone]\" { print $1 }' | xargs -r git branch -D
sync = !git switch `git remote show origin | sed -n '/HEAD branch/s/.*: //p'` && git pull --prune && git delete-merged`
One of my favorite git aliases is "git sync". It fetches the main branch and deletes all local branches merged upstream. 💻
Code 👉
Embedding YouTube videos?
Add ?rel=0 to the embed URL to hide those distracting "More videos" suggestions at the end.
Keep your audience focused on YOUR content! 💡
One underrated skill for a software engineer is to design database tables/collections/fields and such. There is surprisingly little content about it, and it is an essential skill for most projects.
The book is about an astronomer chasing a computer hacker who broke into a computer at the Lawrence Berkeley National Laboratory in 1986.
My favourite book of 2024 was The Cuckoo's Egg: Tracking a Spy Through the Maze of Computer Espionage. 📖
It's an amazing book, especially when you realize this is a real story, not just a novel 🤩
www.goodreads.com/book/show/18...
It’s like 1978 all over again
Here are some tips on how to write less JavaScript. People often write JS for things that the browser can do automatically.
What tips do you have where we can use CSS instead of JavaScript? 🤔
tips.rstankov.com/p/tips-for-u...
Didn't know about `direct` and `resolve` might handle this custom URL, I want to get. Thanks a lot 🙌
People always ask how to become a top engineer. One easy trick is to check your production error tracking weekly and fix several errors every week.
Engaging with your production error tracker is not just about fixing errors. It's a valuable learning journey.
The next day, I used some of the techniques we talked about 🙌
I uploaded my screen recording from the recent Ruby Banitsa conf. It's pretty loose and informal!
We had a really fun conversation towards the end with @rstankov.bsky.social and @ventsi.bsky.social chiming in! Hope my mic picked it up 😂
www.youtube.com/watch?v=Md90...
ActiveJob::Performs ActiveJob::Performs adds a performs class method to make the model + job loop vastly more conventional. You use it like this: class Post < ApplicationRecord performs :publish # Or `performs def publish`! def publish # Some logic to publish a post end end Then we build a job for the instance method and define a post.publish_later instance method, and more: class Post < ApplicationRecord class Job < ApplicationJob; end # We build a general Job class to share configuration between method jobs. # Individual method jobs inherit from the `Post::Job` defined above. class PublishJob < Job # We generate the required `perform` method passing in the `post` and calling `publish` on it. def perform(post, *, **) = post.publish(*, **) end # On Rails 7.1, where `ActiveJob.perform_all_later` exists, we also generate # a bulk method to enqueue many jobs at once. So you can do this: # # Post.unpublished.in_batches.each(&:publish_later_bulk) def self.publish_later_bulk ActiveJob.perform_all_later all.map { PublishJob.new(_1) } end # We generate `publish_later` to wrap the job execution forwarding arguments and options. def publish_later(*, **) = PublishJob.perform_later(self, *, **) def publish # Some logic to publish a post. end end
Benefits Conventional Jobs: they'll now mostly call instance methods like publish_later -> publish. Follows Rails' internal conventions: this borrows from ActionMailbox::InboundEmail#process_later calling process and ActionMailer::Base#deliver_later calling deliver. Clarity & less guess work: the _later methods standardize how you call jobs throughout your app, so you can instantly tell what's happening. Less tedium: getting an instance method run in the background is just now a performs call with some potential configuration. Fewer files to manage: you don't have to dig up something in app/jobs just to learn almost nothing from the boilerplate in there. Remaining jobs stand out: app/jobs is way lighter, so any jobs in there that don't fit the performs pattern now stand out way more. More consolidated logic: sometimes Job classes house model-level logic, but now it's all the way out in app/jobs instead of app/models, huh? Tip On that last point, performs does put more logic back within your Active Records, so if you need further encapsulation to prevent them growing too large, consider checking out active_record-associated_object.
Praise from people Here's what @claudiob had to say after using ActiveJob::Performs: I’ve been using active_job-performs for the last month and I love it love it love it!! Your thought process behind it is so thorough. I have a bunch of jobs now attached to models and my app/jobs folder… is empty!! This saves me a lot of mental hoops, I don’t have to switch between files anymore, everything is self-contained. Thank you!!! From @andycroll in a writeup about launching UsingRails: I’ve also adopted a couple of gems—with exceptional Rails-level taste and author pedigree—that I hadn’t used in anger before, including active_job-performs from Kasper […]. Would recommend both. And @nshki after trying it: Spent some time playing with @kaspth's ActiveRecord::AssociatedObject and ActiveJob::Performs and wow! The conventions these gems put in place help simplify a codebase drastically. I particularly love ActiveJob::Performs—it helped me refactor out all ApplicationJob classes I had and keep important context in the right domain model.
I've been polishing up the github.com/kaspth/activ... README.
You can now see all the benefits and more praise quotes now that people are seeing this in practice — I'm really proud of where this is going! 🚀
2024 is the year with the most Ruby talks in a single year, ever!
This is the first time we beat the previous all-time record from 2015!
Ruby is so back!
ISO 8601 has a standard for durations 📅
en.wikipedia.org/wiki/ISO_860...
This is very well supported. Ruby on Rails Active Support works with it and they are many JS libraries.