Version 5 of the Ruby Redis gem removes Redis.current

Redis.current will be removed without replacement in redis-rb 5.0.
Version 4.6.0 adds deprecation warnings for Redis.current and Redis.current=:

`Redis.current=` is deprecated and will be removed in 5.0.

If your application still uses Redis.current, you can only fix it by no longer using it. Here is how.

Redis.new when you need it

You can easily instantiate a Redis client when you need it.

There is probably already a constant like REDIS_URL that you use to configure Sidekiq or similar. So just use that one.

``...

Setup Sidekiq and Redis

If you want Sidekiq to be able to talk to Redis on staging and production servers, you need to add the following to your configuration:

# config/initializers/sidekiq.rb
require 'sidekiq'

Sidekiq.configure_client do |config|
  config.redis = { url: REDIS_URL }
end

Sidekiq.configure_server do |config|
  config.redis = { url: REDIS_URL }
end

The following step may be skipped for new Sidekiq 6+, since it isn't recommended anymore to use a global redis client.

# config/initializers/redis.rb
require 'redis'
require_relativ...

Setting up Tomcat to use an existing OpenSSL certificate

This is for those who already own an SSL certificate (e.g. using it in the Apache HTTP Server) and need to feed it to a Tomcat application. The main issue is that you need to convert your OpenSSL certificate for Java to use it in its keystore.

Create a keystore

This is the place where the application usually gets its keys from. The keytool is able to read certificate files but does not understand private key files which you need to use y...

Fixing "identify: not authorized"

Ubuntu has decided to disable PDF processing because ImageMagick and the underlying Ghostscript had several security issues.

When your Ghostscript is up to date (and receiving updates regularly), you can safely reactivate PDF processing on your computer like this:

  1. Open /etc/ImageMagick-6/policy.xml (requires sudo)
    • For older versions of Ubuntu (or possibly ImageMagick), the path is /etc/ImageMagick/policy.xml
  2. Remove/Comment lines after <!-- disable ghostscript format types -->

If you need ...

Rails: render a template that accepts a block by using the layout option of render

Let's say you have a form that you render a few times but you would like to customize your submit section each time. You can achieve this by rendering your form partial as layout and passing in a block. Your template or partial then serves as the surrounding layout of the block that you pass in. You can then yield back the form to the block and access the form in your block.

-# record/_form.haml

= form_for record do |form|
  -# ...
  .form-actions
    yield(form)
  

In order to make your template record/_form.haml accept a...

Change / Update SSL certificate for Amazon Elastic Load Balancer

There is a new card about how to do this with the new AWS Command Line Interface


At first you need the IAM Cli Tools.
-------------------------------------------------------------------------------------------------------------...

Five years of "Today I Learned" from Josh Branchaud

The linked GitHub repository is a bit like our "dev" cards deck, but groomed from a single person (Josh Branchaud). It includes an extensive list of over 900 TILs on many topics that might be interesting for most of us. (e.g. Ruby, Rails, Git, Unix..)

Ruby

Here is an excerpt of all the Ruby TILs that were new to me. I encourage you to take your time to skim over the original list as well!

Get rid of WARNING: Nokogiri was built against LibXML version 2.7.7, but has dynamically loaded 2.7.8

If you get this warning on your local machine one of these steps might help:

Rebuilt the gem with the newer library

gem install --no-rdoc --no-ri nokogiri -- --with-xml2-include=/opt/local/include/libxml2 --with-xml2-lib=/opt/local/lib

If you still get the error, try to uninstall all nokogiri versions with

gem uninstall nokogiri

and install nokogiri again.

Fixing the issue on servers

However, on our servers this probably will not work. On the server, gems are stored in the ../shared/bundle/ruby/:version/gems dire...

Make Capistrano use SSH Key Forwarding

When deploying code with Capistrano (depending on your configuration) at some point Capistrano tries to check out code from your repository. In order to do so, Capistrano connects to your repository server from the application server you're deploying to with SSH. For this connection you can use two SSH keys:

  • the user's ~/.ssh/id_rsa [default]
  • the very same key you used for connecting to the application server - forwarded automatically to the git repository.

If you prefer the second way, add this to deploy.rb:

ssh_options[:forwar...

Mock the browser time or time zone in Selenium features

In Selenium features the server and client are running in separate processes. Therefore, when mocking time with a tool like Timecop, the browser controlled by Selenium will still see the unmocked system time.

timemachine.js allows you to mock the client's time by monkey-patching into Javascript core classes. We use timemachine.js in combination with the Timecop gem to synchronize the local browser time to the ...

Rails: Rest API post-mortem analysis

This is a personal post-mortem analysis of a project that was mainly build to provide a REST API to mobile clients.

For the API backend we used the following components:

  • Active Model Serializer (AMS) to serializer our Active Record models to JSON.
  • JSON Schema to test the responses of our server.
  • SwaggerUI to document the API.

It worked

The concept worked really good. Here are two points that were extraordinary compared to normal Rails project with many UI components:

  • Having a Rails application, that has no UI components (only...

How to downgrade Google Chrome in Ubuntu

If you're experiencing problems with your Google Chrome installation after an update, it might help downgrading Chrome to check if the problem disappears. Keep in mind though that running outdated software, especially web browsers, is in most cases not a good idea. Please verify periodically if you still need to run the old version or if an even more recently updated version fixes the problems introduced in your version.

Here's how to get old versions of Chrome for your Ubuntu installation:

First, go to [UbuntuUpdates](https://www.ubuntuup...

Chromedriver: Connect local chromedriver with docker

Debugging your integration tests, that run a headless Chrome inside a docker image, is tricky.

In many cases you can connect your Chrome to a remote docker container like docker-selenium, which should be the preferred way when you try to inspect a page within your integration test.

Otherwise you might be able to start your docker container with --net=host and access your local chromedriver in the host address space host.docker.internal.

If both options above don't work for you here is a...

Read your mail in networks that forbid e-mail traffic

If you are connected with a network that forbids e-mail traffic but allows SSH, you can tunnel your e-mail connection through a trusted, intermediary server:

 sudo ssh -i /home/local-user/.ssh/local-user.key -L 143:mail-server.tld:143 remote-user@trusted-server.tld

Explanation for the command above:

| sudo | Secure ports may only be forwarded by root |
| ssh -i /home/local-user/.ssh/local-user.key | Private half of your SSH key for the trusted server |
| -L 143:mail-server.tld:143 | Forward connections to port 143 on your mail s...

MySQL: Disable query cache for database profiling

If you want to see how long your database queries actually take, you need to disable MySQL's query cache. This can be done globally by logging into a database console, run

SET GLOBAL query_cache_type=OFF;

and restart your rails server.

You can also disable the cache on a per query basis by saying

SELECT SQL_NO_CACHE * FROM ...

You also probably want to disable Rails internal (per-request) cache. For this, wrap your code with a call to ActiveRecord::Base.uncached. For example, as an around_filter:

d...

Debugging your Webpack build time with Speed Measure Plugin

If your Webpack build is slow, you can use the Speed Measure Plugin for Webpack to figure out where time is being spent.
Note that at time of writing, Webpack 5 seems unsupported. It works on Webpack 4, though.

Wire it into your application as described in the library's documentation:

  1. Hook into your environment file, e.g. config/webpack/development.js and instead of exporting your Webpack config,...

esbuild: Make your Rails application show build errors

Building application assets with esbuild is the new way to do it, and it's great, especially in combination with Sprockets (or Propshaft on Rails 7).
You might be missing some convenience features, though.

Here we cover one specific issue:
Once you have started your development Rails server and esbuild with the --watch option (if you used jsbundling-rails to set up, you probably use bin/dev), esbuild will recompile your assets upon change, but build errors will only be printed to the terminal. Your application won't complain about them ...

Debugging Capistrano

Capistrano 3 has a doctor task that will print information about

  • Environment: Ruby, Rubygems and Bundler versions
  • List of Capistrano gems and whether an update is available
  • All config variables and their values
  • Capistrano server config
$ bundle exec cap staging doctor

Heads up: Deployment with newly generated SSH key (using ED25519) might fail

If you use a newer SSH key generated with the ED25519 algorithm instead of RSA (see Create a new SSH key pair), the deployment with Capistrano may fail with the following message:

The deploy has failed with an error: unsupported key type `ssh-ed25519'
net-ssh requires the following gems for ed25519 support:
 * ed25519 (>= 1.2, < 2.0)
 * bcrypt_pbkdf (>= 1.0, < 2.0)
See https://github.com/net-ssh/net-ssh/issues/565 for more information
Gem::LoadError : "ed25519 i...

Missing certificates for rubygems and bundler in Ruby 1.8.7

Using Ruby 1.8.7 you will not be able to use the maximum versions Rubygems 1.8.30 and Bundler 1.17.3 with https://rubygems.org/ anymore. This is a result of a server certificate on December 5th, 2020. The resulting errors will look like following:

  • TypeError: can't modify frozen object
  • Could not verify the SSL certificate for https://rubygems.org/*
  • Bundler::Fetcher::CertificateFailureError: Could not verify the SSL certificate for https://index.rubygems.org/versions.
  • `Error fetching data: hostname was not m...

jQuery and cross domain AJAX requests

When making cross-domain AJAX requests with jQuery (using CORS or xdomain or similar), you will run into issues with HTTP headers:

  • jQuery will not set the X-Requested-With header. On your server, requests will not look like AJAX requests (request.xhr? will be false).
  • jquery-ujs will not set CSRF headers.

This is by design and improves secu...

Better HTML forms: use type, inputmode, enterkeyhint and autocomplete

Web forms can be made much more usable with a few HTML attributes. Short summary:

  • type: Tells browsers about the input data type. Mobile browsers will select a virtual keyboard based on this value. Some browsers will add simple validation, e.g. for type email.
  • inputmode: Direct hint about the virtual keyboard to use. Inferred from type, but can be very handy when ...

How to fix "unknown role" errors in Capistrano recipes

When you have a complex recipe setup with multistage deployment you may run into this error:

`role_list_from': unknown role `something' (ArgumentError)

Consider this task definition:

namespace :foo do
  task :bar, :roles => :something do
    # do crazy stuff
  end
end

Whenever we call foo.bar in our recipe, Capistrano will fail if you deploy to a stage where none of the servers has the role the error complains about, "something" in this case.

However, you can [hack around it](http://groups.google.com/group/ca...

Carrierwave: How to migrate to another folder structure

A flat folder structure can be cool if you have only a few folders but can be painful for huge amounts. We recently had this issue in a project with more than 100.000 attachments, where we used a structure like this /attachments/123456789/file.pdf.

Even the ls command lasted several minutes to show us the content of the attachments folder.

So we decided to use a more hierarchical structure with a limited maximum of folder per layer. Here are a few tips how to migrate your files to their new...