Triggering JavaScript when an element is clicked

Often people need links which are not linked directly, but should trigger execution of javascript.

You can find a lot of workarounds for that:

  • <a href="#">Do something with js!</a>
    This defines an empty anchor. This may lead the browser to let the page jump to the top when the link is clicked, unless you call preventDefault on the event. This is probably not what you want.

  • <a href="#!">Do something with js!</a>
    This tells the browser to jump to an anchor !. It depends on the browser implementation what happens when an anc...

Auto-generating plain-text bodies for HTML e-mails in Rails apps

When building an application that sends e-mails to users, you want to avoid those e-mails from being classified as spam. Most obvious scoring issues will not be relevant to you because you are not a spammer.

However, your application must do one thing by itself: When sending HTML e-mails, you should include a plain-text body or tools like SpamAssassin will apply a significant score penalty. Here is how to do that automatically.

  1. Add premailer-rails to your Gemfile and bundle.
  2. Done! ...

DNS debug tools

There are several tools for DNS debugging which offer you more or less information. Most of the time the more simple ones, like host oder nslookup will be sufficient.

host

simple DNS lookup utility.

>host heise.de
heise.de has address 193.99.144.80
heise.de has IPv6 address 2a02:2e0:3fe:1001:302::
heise.de mail is handled by 10 relay.heise.de.

nslookup

query Internet domain name servers. Nslookup has two modes: interactive and non-interactive.

>nslookup heise.de
Server:		146.254.160.30
Address:	146.254.160.3...

RSpec matcher to compare two HTML fragments

The RSpec matcher tests if two HTML fragments are equivalent. Equivalency means:

  • Whitespace is ignored
  • Types of attribute quotes are irrelevant
  • Attribute order is irrelevant
  • Comments are ignored

You use it like this:

html = ...
expect(html).to match_html(<<~HTML)
  <p>
    Expected content
  </p>  
HTML

You may override options from CompareXML by passing keyword arguments after the HTML string:

html = ...
expect(html).to match_html(<<~HTML, ignore_text_nodes: true)
 ...

Why has_many :through associations can return the same record multiple times

An association defined with has_many :through will return the same record multiple times if multiple join models for the same record exist (a n:m relation). To prevent this, you need to add ->{ uniq } as second argument to has_many (below Rails 4 it is a simple option: has_many :xyz, :uniq => true).

Example

Say you have an Invoice with multiple Items. Each Item has a Product:

class Invoice < ActiveRecord::Base
  has_many :items
  has_many :products, :through => :items
end

class Item < ActiveRecord::Base
  ...

Git: Switching back to the previous branch

Using git checkout - you can switch back to the branch you previously worked on.

(master) $ git checkout foobar
Switched to branch 'foobar'
(foobar) $ git checkout -
Switched to branch 'master'
(master) $

This also works with other commands like git merge:

(master) $ git checkout foobar
Switched to branch 'foobar'
(foobar) $ git merge -
Merged branch 'master'

Rails: Testing file downloads with request specs

tl;dr

Prefer request specs over end-to-end tests (Capybara) to joyfully test file downloads!

Why?

Testing file downloads via Capybara is not easy and results in slow and fragile tests. We tried different approaches and the best one is just okay.

Tests for file downloads via Capybara ...

  • ... are slow,
  • ... are fragile (breaks CI, breaks if Selenium driver changes, ...),
  • ... need workarounds for your specia...

List of handy Ruby scripts to transcode different file types (often by using GPT)

It's 2024 and we have tools like ffmpeg, imagemagick and GPT readily available. With them, it's easy to convert texts, images, audio and video clips into each other.

For the everyday use without any parameter tweaking I'm using a collection of tiny scripts in my ~/bin folder that can then be used as bash functions. And: It's faster to use the CLI than interacting with a website and cheaper to use the API than buying GPT plus.. :-)

Usage

  • text-to-image "parmiggiano cheese wedding cake, digital art"
  • `text-to-audio "Yesterday I ate ...

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...

Carrierwave processing facts

  1. Class-level process definitions are only applied to the original file
  2. Versions are generated based on the processed original file
  3. Callbacks (before/after) are applied to original file and each version by itself
  4. Under the hood, a version is an instance of the uploader class that has no versions
  5. Version uploader and original uploader can be distinguished by checking #version_name: version uploaders return the version name, whereas the original uploader instance returns nil
  6. Version instances do not have a re...

Ubuntu: Disable webcam microphone

If you want to system-wide disable the microphone of your external webcam in PulseAudio use the following one-liners:

# Connected cards
$ pactl list short cards
1       alsa_card.pci-0000_00_1f.3      module-alsa-card.c
5       alsa_card.usb-Lenovo_ThinkPad_Thunderbolt_4_Dock_USB_Audio_000000000000-00      module-alsa-card.c
6       alsa_card.usb-HD_Webcam_C270_HD_Webcam_C270-02  module-alsa-card.c

# Disable  HD_Webcam_C27
$ pactl list short cards | grep HD_Webcam_C27 | cut -f2 | xargs -rt -I % pactl set-card-profile % off
pactl s...

Geordi 10.0.0 released

10.0.0 2024-03-07

Compatible changes

  • console command: You can now globally disable the IRB multiline feature by setting irb_flags: --nomultiline in ~/.config/geordi/global.yml. All configured irb_flags are automatically passed on to the console IRB.
  • console command: Ctrl + C now properly exits a local Rails console
  • rspec and cucumber commands: Run specs even if the automatic chromedriver update fails
  • Improve detection of IRB version
  • Add new hints to 'Did you know'

Breaking changes

  • dump command: Drop...

Chaining Capybara matchers in RSpec

You can chain multiple Capybara matchers on the page or any element:

expect(page)
  .to have_content('Example Course')
  .and have_css('.course.active')
  .and have_button('Start')

When you chain multiple matchers using and, [Capybara will retry the entire chain](https://github.com/teamcapybara/capybara/blob/c0cbf4024c1abd48b0c22c2930e7b05af58ab284/lib/capybara/rspec/matc...

Understanding z-index: it's about stacking contexts

The CSS property z-index is not as global as you might think. Actually, it is scoped to a so-called "stacking context". z-indexes only have meaning within their stacking context, while stacking contexts are treated as a single unit in their parent stacking context. This means indices like 99999 should never actually be needed.

Creating a new stacking context

In order to create a stacking context with the least possible side effects, use the isolation property on an...

Imagemagick: Batch resize images

Trick: Do not use convert but mogrify:

mogrify -resize 50% *

This overwrites the original image file.

In contrast, convert writes to a different image file. Here is an example if you need this:

cd /path/to/image/directory
for i in `ls -1 *jpg`; do convert -resize 50% $i "thumb_$i"; done