FastRuby.io

FastRuby.io

@fastruby.io

Productized services by @OmbuLabs.ai to remediate technical debt in #Ruby and #Rails applications. Open source contributors and maintainers.

29 followers8 following220 posts

errors.messages used to be a hash you could poke at directly. Rails 6.1 turned errors into queryable objects (errors.where, of_kind?) and Rails 7.0 dropped the old deprecated methods. go.fastruby.io/6by #RailsUpgrade

ImageMagick alone accounts for 161 of 378 CVEs across libvips and its dependencies. Hot Cell stops patching and sandboxes Active Storage processing instead: go.fastruby.io/igg #RubyOnRails #AppSec

Rails API recall across AI models ranged from 8% to 41%. Asked to normalize emails, models wrote before_validation callbacks instead of using normalizes. Measure it on your app: go.fastruby.io/y1n #RubyOnRails #AI

A volunteer-run chess federation with no engineering budget, five minor Rails versions, and one hidden shim a model wouldn't have flagged on its own: go.fastruby.io/rn8 #RubyOnRails #RailsUpgrade #TechDebt

We have done ~40 Rails 3.2 to 4.2 upgrades and only ~10 from 6.1 to 7.1. The difference is not difficulty, it is whether the team ever agreed to stay one minor version behind. go.fastruby.io/idh #RailsUpgrade

FastRuby.io reposted

Replying to @fastruby.io

The trap with a stopgap this clean is that it works, so nobody remembers it is there. Worth leaving a dated comment and a ticket next to it, or in six months it is just config nobody can explain.

A full rewrite bets everything on one release after months of work, with no validation until launch. Strangler fig migrates one capability at a time, and the debt only drops once the old path is deleted. go.fastruby.io/1j3 #TechnicalDebt #LegacyCode

Power HRG went from 60 servers at 2 processes each to 20 servers at 6 to 8. Wait time fell from 20 to 50ms to almost zero, and the server bill went down with it. go.fastruby.io/407 #RailsPerformance

Mixed string and symbol keys in a delegated hash is how Ruby 3 hands you an ArgumentError with no obvious cause. ActiveJob keeps the distinction, Sidekiq flattens it through JSON. go.fastruby.io/wl4 #Ruby

Herb just got merged into Rails. Running it against our own views turned up problems in 21 templates and 1,404 lint offenses, over half of them autofixable. go.fastruby.io/yfs #Rails #TechnicalDebt

The AI is not replacing Rails conventions, it is orchestrating them. Generators, Rake tasks and a well designed CLI are the interface a coding agent actually needs. go.fastruby.io/8ya #Rails

Three attempts at a Rails task with GPT-5.4, ten to fourteen steps each: $0.42 total. The open-sourced lemans harness lets you run that math on your own app instead of trusting a generic leaderboard. go.fastruby.io/s61 #RailsUpgrade #AIAgents

We updated our Ruby 4.0 piece: there's now a tracking issue for Ruby Box support in RubyGems and Bundler. Also worth knowing, 8 Ractors used about 7x less memory than 8 forked workers in one benchmark. go.fastruby.io/5y0 #Ruby4 #Ractors

An upgrade isn't finished when the tests pass. Drop the dual boot conditionals, swap in Gemfile.next.lock, and actually read the new_framework_defaults file before adopting it wholesale. go.fastruby.io/hps #RailsUpgrade

Budget about 3 minutes of downtime per GB when you copy a deprecated Heroku Postgres into a new database, and keep the old one a few days as your cheapest rollback. go.fastruby.io/1a0 #Rails

One controller went from 39% to 60% covered once the Cypress runs counted. Nobody wrote a new test: the Rails server just runs outside SimpleCov's test lifecycle. go.fastruby.io/tpo #Rails #Testing

post.comments.update(id, ...) used to happily write to a comment on a different post. Rails 8.2 raises RecordNotFound instead. The Rails team calls the old behavior an oversight. go.fastruby.io/qis #RubyOnRails

ZJIT compiles whole methods through an SSA-based IR instead of YJIT's basic blocks. It is faster than the interpreter and not yet as fast as YJIT, which is the honest part of the pitch. go.fastruby.io/bbd #Ruby

Dual-booting a gem is one BUNDLE_GEMFILE swap. Dual-booting Ruby means the version lives in your Gemfile, your CI matrix, and your version manager, so a next? helper in the Gemfile is where it starts. go.fastruby.io/oqn #Ruby

Your coverage number is not just low, it is wrong about which code is untested. Everything Cypress exercises is invisible to SimpleCov, so you end up writing tests for lines already covered. go.fastruby.io/g76 #Ruby #Testing

Running the new code next to the old one is not the win. #TechDebt only drops when you delete the legacy path. Shadow-log both, compare, then flip the flag. go.fastruby.io/sow #LegacyCode #StranglerFig #DesignPatterns

#SimpleCov 1.0 filters test directories by default when you call start with no arguments, so your coverage number can drop without a single line changing. Recalibrate the baseline before you panic. go.fastruby.io/xfr #Ruby

Parallelizing your RSpec test suite could produce massive performance gains. For example: Nearly 2 hours down to under 5 minutes! Here is the part teams skip: isolating Redis and cache per worker, not just the database. go.fastruby.io/vo1 #RSpec #Ruby #Performance