How to find out what is running on a port on a remote machine

By convention, common protocols use a defined port, like 80 for HTTP or 443 for HTTPS.

You can use nmap to find out what service is running behind a given port, and most often see some details about it. This can be helpful if servers don't offer the services you expect for some ports. If you'd like to see what ports are listing on your local machine, you might want to use ss instead of nmap.

Note that nmap's service discovery may trigger several requests.

Example

When using nmap, adding the -A switch will ...

The TCF 2.0 (Tranparency and Consent Framework) standard, and what you should know about it

The Interactive Advertising Bureau (IAB) is a European marketing association which has introduced a standard how advertising can be served to users in line with the General Data Protection Regulation (GDPR). This standard is called the TCF 2.0 (Transparency and Consent Framework). If you want to integrate any kind of advertising into a website, chances are the advertising network will require your website to implement that standard. This is a very brief overview of what this means:

The basic idea in the TCF 2.0 ...

Be very careful with 301 and 308 redirects

Browsers support different types of redirects.

Be very careful with these status codes:

  • 301 Moved Permanently
  • 308 Permanent Redirect

Most browsers seem to cache these redirects forever, unless you set different Cache-Control headers. If you don't have any cache control headers, you can never change them without forcing users to empty their cache.

Note

By default Rails sends a ...

Concurrency issues with find-as-you-type boxes

Find-as-you-type boxes are usually built by observing changes in a text field, and querying the server via AJAX for search results or suggestions when the field has changed.

A common problem with this implementation is that there is no guarantee that AJAX responses are evaluated in the same order as the original requests. The effect for the user is that the search results are flashing back and forth while the user is typing the query, and when the user has stopped typing the last results don't always match the final query.

Workarounds
----...

How to silence Puma for your feature tests

When RSpecs runs the first feature spec, you may see log output like this:

Capybara starting Puma...
* Version 6.5.0, codename: Sky's Version
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:39949

You can disable this behavior by tweaking Capybara's Puma server in your spec/support/capybara.rb:

Capybara.server = :puma, { Silent: true }

Note

You don't need to configure this if you're using system tests with modern versions of Rails. They do [exactly the same](https://github.com/rails/rails/blob/ma...

Better numeric inputs in desktop browsers

You want to use <input type="number"> fields in your applications.
However, your desktop users may encounter some weird quirks:

  1. Aside from allowing only digits and decimal separators, an "e" is also allowed (to allow scientific notation like "1e3").
    • Non-technical users will be confused by this.
    • Your server needs to understand that syntax. If it converts only digits (e.g. to_i in Ruby) you'll end up with wrong values (like 1 instead o...

Generating test images on the fly via JavaScript or Ruby

When you need test images, instead of using services like lorempixel or placehold.it you may generate test images yourself.

Here we build a simple SVG image and wrap it into a data: URI. All browsers support SVG, and you can easily adjust it yourself.
Simply set it as an image's src attribute.

JavaScript

Simple solution in modern JavaScript, e.g. for use in the client's browser:

function svgUri(text) {
  let svg = `
    <svg wid...

Capistrano task to edit staging / production credentials

When using Rails credentials, you will edit the encrypted credentials for staging or production environments from time to time. To do that you need the secret key which should only live on the servers.

Do not download these key files to your local dev environment. They are sensitive and must not be stored on your machine.

Instead, put the attached capistrano task into lib/capistrano/tasks/ of your application. It expects environment specific keys to live in :shared_path/config/credentials/:stage.key. If you have a single master.key...

Popular mistakes when using nested forms

Here are some popular mistakes when using nested forms:

  • You are using fields_for instead of form.fields_for.
  • You forgot to use accepts_nested_attributes in the containing model. Rails won't complain, but nothing will work. In particular, nested_form.object will be nil.
  • The :reject_if option lambda in your accepts_nested_attributes call is defined incorrectly. Raise the attributes hash given to your :reject_if lambda to see if it looks like you expect.
  • If you are nesting forms into nested forms, each model involved ne...

When does Webpacker compile?

Webpack builds can take a long time, so we only want to compile when needed.

This card shows what will cause Webpacker (the Rails/Webpack integration) to compile your assets.

When you run a dev server

While development it is recommended to boot a webpack dev server using bin/webpack-dev-server.

The dev server compiles once when booted. When you access your page on localhost before the initial compilation, the page may load without assets.

The ...

JavaScript: Comparing objects or arrays for equality (not reference)

JavaScript has no built-in functions to compare two objects or arrays for equality of their contained values.

If your project uses Lodash or Underscore.js, you can use _.isEqual():

_.isEqual([1, 2], [2, 3]) // => false
_.isEqual([1, 2], [1, 2]) // => true

If your project already uses Unpoly you may also use up.util.isEqual() in the same way:

up.util.isEqual([1, 2], [2, 3]) // => false
up.util.isEqual([1, 2], [1, 2]) // => true

If you are wri...

JavaScript: Sharing content with the native share dialog

Mobile Chrome and Safari support the "web share API" which allow you to use the native share functionality of an Android or iOS phone. Some desktop OSs like Windows or MacOS also support native share dialogs. See Can I Use for a detailed support matrix.

When clicking a share button using this API, the browser will automatically show all installed applications that support content sharing, such as Whatsapp, Facebook, Twitter, e-mail etc.

The API is extremely simple to use:

if ...

ActiveRecord: String and text fields should always validate their length

If you have a :string or :text field, you should pair it with a model validation that restricts its length.

There are two motivations for this:

  • In modern Rails, database types :string and :text no longer have a relevant size limit. Without a validation a malicious user can quickly exhaust the hard drive of your database server.
  • In legacy Rails (or database schemas migrated from legacy Rails), database types :string and :text had a database-side length constraint. When the user enters a longer string, the ActiveRecord valida...

Use <input type="number"> for numeric form fields

Any form fields where users enter numbers should be an <input type="number">.

Numeric inputs have several benefits over <input type="text">:

  • On mobile or tablet devices, number fields show a special virtual keyboard that shows mostly digit buttons.
  • Decimal values will be formatted using the user's language settings.
    For example, German users will see 1,23 for <input type="number" value="1.23">.
  • Values in the JavaScript API or when submitting forms to the server will always use a point as decimal separator (i.e. "1.23" eve...

open-next-failure: An alias to speed up test debugging

Getting an entire test suite green can be a tedious task which involves frequent switches between the CLI that is running tests back to the IDE where its cause can be fixed.

The following bash aliases helped me speed up that process:

alias show-next-failure="bundle exec rspec --next-failure"
alias open-next-failure="show-next-failure || show-next-failure --format json  | jq -r '.examples[0]' | jq '\"--line \" + (.line_number|tostring) + \" \" + .file_path' | xargs echo | xargs rubymine"

There is a lot going on above but the gist...

How Rails chooses error pages (404, 500, ...) for exceptions

When your controller action raises an unhandled exception, Rails will look at the exception's class and choose an appropriate HTTP status code and error page for the response.

For instance, an ActiveRecord::RecordNotFound will cause Rails to render a red "The page you were looking for doesn't exist" with a status code of "404" (not found).

The mapping from exception classes to error types is a hash in Rails.configuration.action_dispatch.rescue_responses. The...

Devise: Invalidating all sessions for a user

Background information about session storage in Rails

Rails has a default mechanism to store the session in the CookieStore. This is a cookie which holds the entire user session hash in the browser. This cookie is serialized, encoded with base64, and signed.

How Devise handles authentication

Devise uses this CookieStore. To track a users session, a salt is stored in the session ...

Test your application's e-mail spam scoring with mail-tester.com

You can use mail-tester.com to check your application's e-mails for issues that might cause e-mails to be classified as spam.

They provide a one-time e-mail addresses that you can use to sign up etc. You can then check for scoring results of SpamAssassin and other potential issues.
You don't need to hit 10/10. Something around 9/10 is perfectly fine.

Note:

  • For password-protected staging sites you will get an error for links that can not be resolved. This is fine, simply check production once available.
  • ...

How to make Webpacker compile once for parallel tests, and only if necessary

Webpack is the future. We're using it in our latest Rails applications.

For tests, we want to compile assets like for production.
For parallel tests, we want to avoid 8 workers compiling the same files at the same time.
When assets did not change, we do not want to spend time compiling them.

Here is our solution for all that.

Its concept should work for all test suites.

Copy the following to config/initializers/webpacker_compile_once.rb. It will patch Webpacker, but only for the test environment:

# Avoid hardcoded asset host...

PSA: Be super careful with complex `eager_load` or `includes` queries

TLDR

Using .includes or .eager_load with 1-n associations is dangerous. Always use .preload instead.

Consider the following ActiveRecord query:

BlogPost.eager_load(
  :comments
  :attachments,
).to_a

(Let's assume we only have a couple of blog posts; if you use pagination the queries will be more complicated, but the point still stands.

Looks harmless enough? It is not.

The problem

ActiveRecord will rewrite this into a query using LEFT JOINs which looks something like this:

SELECT "blog_posts...

Upgrade guide for moving a Rails app from Webpack 3 to Webpack 4

Webpacker is Rails' way of integrating Webpack, and version 4 has been released just a few days ago, allowing us to use Webpack 4.

I successfully upgraded an existing real-world Webpack 3 application. Below are notes on everything that I encountered.
Note that we prefer not using the Rails asset pipeline at all and serving all assets through Webpack for the sake of consistency.

Preparations

  • Remove version locks in Gemfile for webpacker
  • Remove version locks in package.json for webpack and webpack-dev-server
  • Install by ca...

Use Time.current / Date.current / DateTime.current on projects that have a time zone

Basically, you now need to know if your project uses a "real" time zone or :local, and if config.active_record.time_zone_aware_attributes is set to false or not.

  • With time zones configured, always use .current for Time, Date, and DateTime.

    ActiveRecord attributes will be time-zoned, and .current values will be converted properly when written to the database.
    Do not use Time.now and friends. Timezone-less objects will not be converted properly when written to the database.

  • With no/local time zone use Time.now, `...

Capybara: Most okayest helper to download and inspect files

Testing file download links in an end-to-end test can be painful, especially with Selenium.

The attached download_helpers.rb provides a download_link method for your Capybara tests. It returns a hash describing the download's response:

details = download_link('Download report')
details[:disposition]  # => 'attachment' or 'inline'
details[:filename]     # => 'report.txt'
details[:text]         # => file content as string
details[:content_type] # => 'text/plain'

Features

Compared to [other approaches](...

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