How to simulate limited bandwidth in Google Chrome and Firefox

Your development machine is usually on a very good network connection.
To test how your application behaves on a slow network (e.g. mobile), you can simulate limited bandwidth.

Chrome

  • Open the dev tools (Ctrl+Shift+I or F12) and switch to the "Network" tab
  • In the row below the dev tool tabs, there's a throttling dropdown which reads "Online" by default.
  • Inside the dropdown, you will find a few presets and an option to add your own download/upload/latency settings.

Firefox

  • Open the dev tools (Ctrl+Shift+I or F12) and switc...

Ruby object equality

TLDR

if you define a equality method for a class you must also implement def hash.

Ruby has a lot of methods that have to do something with equality, like ==, ===, eql?, equal?. This card should help you differentiate between those and give you hints on how to implement your own equality methods in a safe manner.

Differences between the methods

for everyday use: ==

When you compare two objects in ruby, you most often see the use of foo == bar. By default the == operator inherits from Object and is impl...

Updated: Bash functions to provide repository context for LLM chats

Documented a repomix that allows you to bundle the XML repository context with custom LLM instructions. I have mine located at ~/.config/repomix/instruction.md

ActiveRecord: Cleaning up your database with ignored_colums

Leaving old unused DB columns around after a migration is confusing for other developers. However, dropping columns too eagerly might also cause problems and extra work. If you want to mark columns for future deletion, but are unsure, whether you can simply drop them right now, use these tools:

Add a comment to your DB schema

With schema comments you can add a comment like LEGACY as of yyyy-mm-dd to your DB schema.

Ignore the column

With [igno...

Debugging failed AJAX requests with better_errors

better_errors is an awesome gem for enhanced error pages in development, featuring a live-REPL for some light debugging.

To debug the exception you got on an AJAX-Request, visit /__better_errors on your app's root path (e.g. http://localhost:3000/__better_errors). It shows the error page for the last exception that occurred, even when it has been triggered by an AJAX request.

You can even open files from better_errors with RubyMine on Linux.

Using partials in Rails views

Rails partials have a lot of "hidden" features and this card describes some non-obvious usages of Rails Partials.

Rendering a basic partial

The most basic way to render a partial:

render partial: 'weather' 

This will render a _weather.html.erb file. Notice how all partials need to be prefixed with _.

It's possible to define local variables that are only defined in the partial template.

# _weather.html.erb
<h1>The weather is <%= condition %></h1>

# index.html.erb
render partial: 'weather', locals: { condition: ...

Preloaded associations are filtered by conditions on the same table

When you eagerly load an association list using the .include option, and at the same time have a .where on an included table, two things happen:

  1. Rails tries to load all involved records in a huge single query spanning multiple database tables.
  2. The preloaded association list is filtered by the where condition, even though you only wanted to use the where condition to filter the containing model.

The second case's behavior is mostly unexpected, because pre-loaded associations usually don't care about the circumstances under whi...

Rails: namespacing models with table_name_prefix instead of table_name

When you want to group rails models of a logical context, namespaces are your friend. However, if you have a lot of classes in the same namespace it might be tedious to specify the table name for each class seperately:

class Accounting::Invoice < ApplicationRecord
  self.table_name = 'accounting_invoices'
  ...
end

class Accounting::Payment < ApplicationRecord
  self.table_name = 'accounting_payments'
  ...
end

A replacement for the self.table_name-assignment is the table_name_prefix in the module definition:

modu...

Calling a helper method with the same name as your current partial

Partials always define a local variable with the same name as themselves. E.g. when you are in _recent_users.html.erb, a local variable recent_users will be defined and overshadow any helper method that is also called recent_users().

If you would like to use a helper method recent_users() in a partial _recent_users.html.erb you can say this in the partial template:

<% recent_users = self.recent_users() %>
<% recent_users.each do |user| %>
  ...
<% end %>

How to create giant memory leaks in AngularJS (and other client-side JavaScript)

This guide shows how to create an AngularJS application that consumes more and more memory until, eventually, the browser process crashes on your users.

Although this guide has been written for Angular 1 originally, most of the advice is relevant for all client-side JavaScript code.

How to observe memory consumption

To inspect the amount of memory consumed by your Javascripts in Chrome:

  • Open an incognito window
  • Open the page you want to inspect
  • Press Shift + ESC to see a list of Chrome processes...

Bash functions to provide repository context for LLM chats

I use the Gemini web chat interface quite extensively. One thing that is tedious is giving it all the context it needs to do a proper job. Context engineering is not an easy task, but on the other hand we now have context limits of ~1 million token, which allows us to just dump in everything we have in many cases. And when we do that in the web interface, we can avoid extra costs that would be charged when using the API!

The functions below pack your current work (diffs, full repos, or specific commits) into XML/Diff files, which are then ...

HTTP Client in RubyMine

RubyMine has a HTTP Client that can be useful to test web APIs.
Just create a .http scratch file an write your request in it.
The request can then be executed with the "Run all requests in File" button above the file.

Some alternatives:

The format for request is like this:

Method Request-URI HTTP-Version
Header-field: Heade...

Heads up: network requests `Kernel#open` are not mocked with VCR

We usually rely on VCR and WebMock to prevent any real network connection when running our unit tests.

This is not entirely true: They are both limited to a set of HTTP libraries listed below (as of 2022). Direct calls to Kernel#open or OpenURI#open_uri are not mocked and will trigger real network requests even in tests. This might bite you e.g. in [older versions of CarrierWave](https://github.com/carrierwaveuploader/carrierwave/blob/0.11-stable/lib/carrierwave/upl...

CSS: Don't target multiple vendor-prefixed pseudo-elements in a single rule

Some pseudo-elements need to be addressed with vendor prefixes. E.g. ::selection is not supported by Firefox, you need to use ::-moz-selection instead.

What you cannot do is to define a single CSS rule to address both the standard and vendor-prefixed form:

::selection, ::-moz-selection {
  background-color: red;
}

This rule will be ignored by all browsers. If a browser does not know al...

Logic of `where.not` with multiple attributes

When using where.not with a Hash of multiple attributes, Rails applies logical NAND (NOT (A AND B)).

This contrasts with logical NOR (NOT A AND NOT B), which is achieved by chaining multiple where.not calls.

The difference in logic alters the scope of excluded records:

  • NAND: Excludes records only if they match all attributes simultaneously.
  • NOR: Excludes records if they match any of the attributes.
NAND NOR
![NAND](https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Venn1110.svg/1...

HTTP headers can only transport US-ASCII characters safely

HTTP header values must only contain low-ASCII (7-bit) characters for safe transport. From RFC 7230:

Historically, HTTP has allowed field content with text in the ISO-8859-1 charset [ISO-8859-1], supporting other charsets only through use of [RFC2047] encoding. In practice, most HTTP header field values use only a subset of the US-ASCII charset [USASCII]. Newly defined header fields SHOULD limit their field values to US-ASCII octets.

If you need to transport 8-bit+ characters (e.g...

Knapsack: Rerun a flaky test locally

Knapsack allows you to rerun a specific job locally. This is helpful to run specs in the exactly same order like in the CI.

Example for running rspec 3/8 with a seed output of 20689:

CI_NODE_INDEX=2 CI_NODE_TOTAL=8 bundle exec rake "knapsack:rspec[--seed=20689]"

*Note: the environment variable ...

Beware: Many browsers define window.event

Some browsers define window.event, which will return a copy of the "current" event. However, this is not defined by the W3C. Most importantly, Firefox does not support it, neither do recent versions of IE.

You should completely avoid accessing the global event and instead pass the event object around that the event handler receives. The easiest protection against accidentally accessing window.event is just never naming the event event, but e or evnt or so.

function brokenInFirefox() {
  event.preventDefault() // Brea...

How to split up a git commit

Quick steps

  1. git rebase -i -> mark your commit with edit
  2. git reset HEAD~ (remove the marked commit, but keep its changes)
  3. Make several commits (optionally setting the previous author manually)
  4. git rebase --continue

Detailed instructions

Basically, you will review the last n commits and stop at the splittable commit. Then you'll undo that commit and put its changes into new commits at your liking.

  1. Review commits (rebase)

    git rebase -i HEAD~3
    # or
    git rebase -i origin/master
    

    ...

How to explain SQL statements via ActiveRecord

ActiveRecord offers an explain method similar to using EXPLAIN SQL statements on the database.

However, this approach will explain all queries for the given scope which may include joins or includes.

Output will resemble your database's EXPLAIN style. For example, it looks like this on MySQL:

User.where(id: 1).includes(:articles).explain
EXPLAIN for: SELECT `users`.* FROM `users`  WHERE `users`.`id` = 1
+----+-------------+-------+-------+---------------+
| id | select_type | table | type  | possible_keys |
+----+-...

Always disable autocomplete for date pickers

When we write a form with date fields, we often use graphical data picker like Rome to get a consistent calendar popup on all browsers.

When you integrate a date picker popup, remember to also set autocomplete="off" on the text input that opens the calendar on click. Otherwise the autocomplete suggestions will cover the calendar box and make it unusable:

Image

If you are using a tool like Unpoly you might want to set autocomplete="off" i...

Canceling event propagation

Within an event handler, there are multiple methods to cancel event propagation, each with different semantics.

  • event.preventDefault()

    Only prevents the default browser behavior for the click, i.e. going to a different url or submitting a form.

    When invoked on a touchstart event, this also prevents mouse events like click to be triggered.

  • event.stopPropagation()

    Prevents the event from bubbling up the DOM.

  • `event.st...

Controlling how your website appears on social media feeds

When a user shares your content, a snippet with title, image, link and description appears in her timeline. By default social networks will use the window title, the first image, the current URL and some random text snippet for this purpose. This is often not what you want.

Luckily Facebook, Twitter, etc. lets you control how your content appears in the activity streams. They even have agreed on a common format to do this: OpenGraph <meta> tags that go into your HTML's <head>:

<meta property="og:url" content="http://start.m...