How to use Rails URL helpers in any Ruby class

In Rails 3+, you can use:

class Project
  delegate :url_helpers, to: 'Rails.application.routes'

  def project_path

For Rails 2, use the attached Modularity trait. It will give any Ruby class a method #url_writer, on which you can call URL helpers:

class Foo
  does 'write_urls'
  def self.class_method
  def instance_method

RubyGems can't find bundle executable although Bundler is installed

I had this error:

> gem install bundler
Successfully installed bundler-2.0.1
1 gem installed

> bundle install
Traceback (most recent call last):
	2: from /home/henning/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
	1: from /home/henning/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
/home/henning/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)

The cause was that Bundler 2 requires RubyG…


Merge two arbitrary ActiveRecord scopes

Rails 3+ allows you to join two scopes from arbitrary sources by calling the merge method:

scope1 = User.where(:email => '')
scope2 = User.where(:first_name => 'hans')
merged_scope = scope1.merge(scope2)

merged_scope.all will now trigger a query for the combined scope chain:

SELECT `users`.* FROM `users` WHERE `users`.`email` = '' AND `users`.`first_name` = 'hans'

If you are joining two models, you can also [merge scopes for different models](…

Using ES6 without a transpiler

If your app does not need to support IE11, you can use most ES6 features without a build step. Just deliver your plain JavaScript without transpilation through Babel or TypeScript, and modern browsers will run them natively.

Features supported by all modern browsers include:

  • fat arrow functions (() => { expr })
  • let / const
  • class
  • async / await
  • Promises
  • Generators
  • Symbols
  • Rest arguments (...args)
  • Destructuring

You won't be able to use import and export, or use npm modules.

See this [ES6 compatibility mat…

Linked content

Rails index route for resources named after uncountable substantives

Using uncountable resources is not recommended as it breaks Rails' magic, e.g. when using form_for. You'll always be better off using simple pluralizable resources.

Rails automatically creates path names for routes defined via the resource method. When you put resource 'user' into config/routes.rb, you can call users_path and get the path to the index action in the UsersController: /users.

However, if you have an uncountable resource like Sheep, you cannot access the index action via sheep_path, because it will…

How to create a Basic Auth header value

When doing Basic Authentication, your browser will send an "Authorization" header. Its value is simply a Base64-encoded representation of "username:password" (like when you place credentials in the URL directly). Example for "" with password "secret":

Authorization: Basic dXNlckBleGFtcGxlLmNvbTpzZWNyZXQ=

So, in Ruby, you can create such headers like so:


Note that when speaking to a REST API, you should be using libraries like RestClient or HTTParty which will wrap …

Make ActionMailer use the current request host and protocol for URL generation

When you generate a URL in a mailer view, ActionMailer will raise an error unless you previously configured it which hostname to use. Configuring the correct hostname is quite annoying when you have multiple deployment targets with different hostnames, e.g. a staging server and a production server.

Using the hack below you don't need to configure a default hostname for your mailers. They will always use the hostname for the current request:

class ApplicationController < ActionController::Base

  before_filter :make_action_maile...
Linked contentRepeats

The Easiest Way to Parse URLs with JavaScript

A very clever hack to parse a structured URL object is to create a <a> element and set its href to the URL you want to parse.

You can then query the <a> element for its components like schema, hostname, port, pathname, query, hash:

var parser = document.createElement('a');
parser.href = '';
parser.hostname; // => ''
pathname = parser.pathname; // => '/bar'

if (pathname[0] != '/')
  pathname = '/' + pathname // Fix IE11

One advantag…


How to combine "change", "up", and "down" in a Rails migration

Rails migrations allow you to use a change method whose calls are automatically inverted for the down path. However, if you need to some path-specific logic (like SQL UPDATE statements) you can not define up and down methods at the same time.

If you were to define define all 3 of them, Rails would only run change and ignore up and down. However, Rails 4+ features a helper method called reversible:

class MyMigration < ActiveRecord::Migration


Let the browser choose the protocol

Use protocol independent URLs whenever possible so that the browser will choose the protocol related to the protocol which the page is delivered with.

Example issues

  • When your page is delivered via https and you provide a youtube video only via http the most browsers (e.g. Firefox, Chrome) won't display the video.
  • When you deliver your youtube video via your test which checks that the embeded video is rendered in the view will fail because your test server doesn't use https


Let your lin…


Building web applications: Beyond the happy path

When building a web application, one is tempted to claim it "done" too early. Make sure you check this list.

Different screen sizes and browsers

Desktops, tablets and mobile devices have all different screen resolutions. Does your design work on each of them?

  • Choose which browsers to support. Make sure the page looks OK, is usable and working in these browsers.
  • Use @media queries to build a responsive design
    • If you do not suppo…

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
    • 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 it enabled for an…

Linked contentRepeats

Native share dialog on mobile Chrome

Mobile Chrome (and the Safari Technology Preview) support the "web share API" which allow you to use the native share functionality of an Android phone. 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 ( typeof(navigator.share) === 'function' ) {
let data = {
url: '', title: '', text: '', } ...

Linked contentRepeats

CSS: Matching against attributes and their values (or parts of them)

You probably know that you can use CSS selectors to match against elements and their attributes, such as:

a[title] { /* any <a> that has a "title" */ }
a[data-fancy="true"] { /* any <a> that has their "data-fancy" attribute set to "true" */ }

But there is more: You do not need to match against "full" attribute values but can match against parts of them.

They work in all somewhat modern browsers, and IE9 or later.

Exact match (CSS2)
[foo="bar"] (matches <div foo="bar" />, but not `<div…

Unpoly 0.57.0 released: New params API, compiler improvements and scrolling fixes

This is a major rewrite with many bugfixes, performance improvements and some minor breaking API changes.

Request parameters

To prevent confusion with [up-data], Unpoly now uses the word "params" when talking about form values or request parameters:

  • up.request() option { data } has been renamed to { params }.
  • up.replace() option { data } has been renamed to { params }.

Parameters may be passed in one of the following type…


Ruby tempfiles

Tempfiles get deleted automatically

With the the ruby Tempfile class you can create temporary files. Those files only stick around as long as you have a reference to those. If no more variable points to them, the GC may finalize the object at some point and the file will be removed from the filesystem. If you would try to access your tempfile then using its path (which you stored previously), you would get an error because the file no longer exists.

Unlink your tempfiles when you're done with them

Minify Font Awesome fonts with webpack

Font Awesome 5 is a comprehensive solution for vector icons on your website.

Originally, Font Awesome came as an icon font (plus stylesheets), but recently it can also be used as a pure JavaScript solution (which will render icons as inline <svg> tags), or even as SVG sprites.

All solutions have their pros and cons:

Icon font:

  • little CPU load (no JavaScript)
  • fonts are relatively large
  • 1 extra HTTP request

Javascript + inline SVG:

  • higher CPU load (needs to watch the DOM via mutation observers to ad…
This website uses cookies to improve usability and analyze traffic.
Accept or learn more