Ruby: Reading and writing CSVs

In ruby you can easily read and write CSVs with the standard CSV library class.

On top of this, you can use the gem smarter_csv for reading (not writing) CSVs in a more comfortable way:

  • Keep in mind, that the development of this gem is in an unknown state and the 2.0 release seems to happen never
  • The API will change completely for 2.0, so you might find a bunch of unrelated documentation for 1.2

Here is an example...

How to: Use Ace editor in a Webpack project

The Ace editor is a great enhancement when you want users to supply some kind of code (HTML, JavaScript, Ruby, etc).
It offers syntax highlighting and some neat features like auto-indenting.

For Webpack 3+

Integrate as described in the documentation. For example load ace Editor like this:

  function loadAceEditor() {
    return import(/* webpackChunkName: "ace" */ 'ace-builds/src-noconflict/ace').then(() => {
      return import(/* webpackChunkName: "ace" */ 'ace-builds/webpack-r...

Rubymine FileType mismatch

If your Rubymine does not recognize a file type correctly although you have entered the unmistakeable file extension like material_orders_controller.rb, this may help you:

Causing the Problem

Sometimes you create a new file and forget to enter the ending like material_orders_controller
Rubymine handles such files per default as simple txt files.
You delete this file and create a new one with correct ending: material_orders_controller.rb. But still Rubymine treats this file as text file, no highlighting is available.

What happene...

How to: expand an element's cover area beyond its container

Occasionally, your designer will hand you designs where elements break the layout's horizontal container width, like navigation buttons of a slider that should be at the left/right of the browser window, or simply by applying a background color that reaches until the left and right of the browser window.

In the past, we've done some horrible things to achieve that. Like margin: 0 -10000px plus overflow-x: hidden.
There is a much saner approach.

Consider the following markup:

<body>
  <div class="container">
    <div class="sec...

Katapult 0.5.0 released

New Features

  • Deployment ready for Opscomplete
  • Copying view and controller templates over to target application during
    basics configuration or via new command katapult templates.
  • "Usage" section in README rewritten: Now describes two usage scenarios.

Improvements

  • Generating a fixed Gemfile.lock. Run bundle update after code generation to
    update all gems to recent versions.
  • Better deployment with Webpack
  • Navigation only rendered if requested
  • Some minor fixes

jQuery: How to remove classes from elements using a regular expression

jQuery's removeClass removes the given class string from an element collection. If you want to remove multiple/unknown classes matching a given pattern, you can do that.

For example, consider a DOM node for the following HTML. We'll reference it by $element below.

<div class="example is-amazing is-wonderful"></div>

Option A: Selecting classes, then removing them

You can iterate over existing classes, and select matching ones. The example below is ES6, on ES5 could write something similar using jQuery.grep.

let classes ...

Accessing Rails config in webpack(er)

It is possible to access Rails config (for example secrets) from within your webpack bundles, thanks to rails-erb-loader. When using webpacker, the setup is like this:

  1. Install rails-erb-loader:

    yarn add rails-erb-loader
    
  2. Add this to your config/webpacker/environment.js:

    environment.loaders.prepend('erb', {
      test: /\.erb$/,
      enforce: 'pre',
      use: [{
        loader: 'rails-erb-loader',
      }]
    })
    
  3. Start using erb. For examp...

Does <html> or <body> scroll the page?

TL;DR: All modern browsers default to using the <html> element as the main document viewport. In CSS, prefer to set overflow properties to html (or :root).

Scrolling the main viewport with JavaScript

The browser's main document viewport is also scrollable by default. The element that corresponds to the main viewport is either <html> (document.documentElement) or <body> (document.body). Which one depends on the browser.

When you want to update the current `sc...

Raising JavaScript errors in Ruby E2E tests (RSpec, Cucumber)

A JavaScript error in an E2E test with Selenium will not cause your test to fail. This may cause you to miss errors in your frontend code.

Using the BrowserConsole helper below you can check your browser's error console from your E2E tests.

The following will raise BrowserConsole::ErrorsPresent if there is an error on the browser console:

BrowserConsole.assert_no_errors!

Ignoring errors

You can ignore errors by their exact message:

BrowserConsole.ignore('Browser is burning')

You can ignore errors with me...

HTML file inputs support picking directories

HTML's <input type="file"> accepts a single file. You can allow multiple files via <input type="file" multiple>.
But sometimes, selecting multiple files is not enough and can be cumbersome for the user. Enter webkitdirectory:

<input type="file" webkitdirectory multiple>

Using webkitdirectory switches the browser's file picker to select a directory. All files inside that directory, and inside any nested subdirectories, will be selected for the file input.

This can be useful when users want to upload all files from a nested dire...

Rails < 5: How to get after_commit callbacks fired in tests

If you use transactional_fixtures or the database_cleaner gem with strategy :transaction, after_commit callbacks will not be fired in your tests.

Rails 5+

Rails 5 has a fix for this issue and no further action is needed.

Rails 3, Rails 4

Add the gem test_after_commit to your test group in the Gemfile and you are done. You don't need to change the database strategy to deletion (wh...

Do not use "flex: 1" or "flex-basis: 0" inside "flex-direction: column" when you need to support IE11

Flexbox is awesome. Most of it even works in IE11, but flex: 1 won't work reliably in Internet Explorer.
This it because implicitly sets flex-basis: 0 which IE fails to support properly.

Example

Consider the following HTML and CSS.

<div class="container">
  <div class="child">
    foo
  </div>
  <div class="bar">
    bar
  </div>
</div>
.container {
  display: flex;
  flex-direction: column;
}

.child {
  flex: 1;
}

See it in action at Plunker.

Background

...

HTML forms with multiple submit buttons

Most forms have a single submit button that will save the record when pressed.

Sometimes a form needs additional submit buttons like "accept" or "reject". Such buttons usually attempt a state transition while updating the record.

To process a form with multiple buttons, your server-side code will need to know which button was pressed. To do so you can give each submit button a different [formaction] attribute. This will override the ...

Project management best practices: The story tracker

In general, the tracker should always be the definitive source of truth of what needs to be done as part of a project. If you identify a task that needs to be done, you should create a story. If you learn something that contradicts an existing story, change it.

The tracker can contain two types of stories: Developer stories, and non-developer stories.

Non-developer stories

Non-developer stories should be clearly marked. They usually belong to the PM (or maybe people from the operations team). Those story can take all forms, could just...

How to make changes to a Ruby gem (as a Rails developer)

At makandra, we've built a few gems over the years. Some of these are quite popular: spreewald (> 1M downloads), active_type (> 1M downloads), and geordi (> 200k downloads)

Developing a Ruby gem is different from developing Rails applications, with the biggest difference: there is no Rails. This means:

  • no defined structure (neither for code nor directories)
  • no autoloading of classes, i.e. you need to require all files yourself
  • no active_support niceties

Also, their scope...

Chrome bug: Wrong stacking order when transitioning composited elements

Google Chrome has a subtle rendering bug that hits me once in a while. It usually occurs in sliders with HTML content.

The issue

When a slider contains a composited[1] element, the element will overlap any other element when sliding, being rendered as frontmost element. After the slider has settled, stacking order jumps back to normal.

It seems like Chrome is doing its compositing wrong. This doesn't happen in Firefox.

The cause

The issue only occurs if:

  • two elements A and B are nested inside an element C
  • A overlaps B (part...

Haml: Generating a unique selector for an element

Having a unique selector for an element is useful to later select it from JavaScript or to update a fragment with an Unpoly.

Haml lets you use square brackets ([]) to generate a unique class name and ID from a given Ruby object. Haml will infer a class attribute from the given object's Ruby class. It will also infer an id attribute from the given object's Ruby class and #id method.

This is especially useful with ActiveRecord instances, which have a persisted #id and will hence **generate the same selector o...

Haml: Prefixing a group of attributes

Haml lets you prefix a group of attributes by wrapping them in a hash. This is only possible with the {} attribute syntax, not with the () attribute syntax.

Example: HTML5 data attributes

HTML5 allows you to use arbitrary attributes like data-method and data-confirm. You can prefix a group of data- attributes like this:

%a{href: '/path', data: { method: 'delete', confirm: 'Really delete?' }} Label

This compiles to:

<a data-confirm='Really delete?' data-method='delete' href='/path'>Label</a>

Exa...

Introduction to Google Tag Manager (for web developers who know Google Analytics)

As a web developer, you know Google Analytics (GA). Probably you've dropped the GA snippet into more than one website, maybe you've even used its Javascript API to implement tracking at the event level.

Google Tag Manager (GTM) is a related tool, but on a higher level and thus with much more power. GTM is not a replacement for GA. Rather, it can make GA configurable without changing anything in the application's code base (and much more beyond, see below).

Only prefer GTM if the customer requests it, or if he is updating his tracking r...

Heads up: Rails offers two similar means for text truncation

Rails defines a #truncate helper as well as a method String#truncate.

= truncate("my string", length: 5)
= "my string".truncate(5)

Both are really similar; in fact, the helper invokes the method and improves it with two niceties: support for passing a block (which could e.g. render a "read on" link), and html_safe knowledge.

Prefer the truncate() helper

Warning: truncate() calls html_safe if you're not escaping. FWIW, an HTML string may easily become invalid when truncated, e.g. when a closing tag gets chopped off.
...

Designing HTML emails

The 90s are calling: they want their tables back. Unfortunately, you need them all for laying out your HTML emails.

Email client HTML rendering is way more scattered than browser HTML. While you might have a pretty good understanding of what features and patterns you can use to support all major browsers, I doubt anyone masters this craft for HTML email clients.

The only way to ensure your email looks good (acceptable, at least) in all mail clients, is to check it. Litmus is your go-to solution for this (see below). W...

Using the Ruby block shortcut with arguments

Ruby has this handy block shortcut map(&:to_i) for map { |x| x.to_i }. However, it is limited to argument-less method invocations.

To call a method with an argument, you usually need to use the full block form. A common and annoying case is retrieving values from a list of hashes (imagine using a JSON API):

users = [ { name: 'Dominik', color: 'blue' }, { name: 'Stefan', color: 'red'} ]
names = users.collect do |user|
  user[:name]
end

If you're using Rails 5+, this example is covered by Enumerable#pluck (`users.pluck(:name)...

Checklist: Rails Authentication

Authentication is a special part of web applications. On the one hand, it usually is a crucial security mechanism restrict access to certain people and roles. On the other hand, most users authenticate only once, so it is very unlikely to spot issues by accident.

So, here comes a quick checklist to help you verifying your authentication solution is all set.

  • This should be default: use HTTPS with HSTS. The HSTS part is important.
  • Use a reliable authentication solution, e.g. [Compose Rails authentication primitives](https://makandracards...

Printing background color of elements

Browsers' printing methods usually don't print background colors. In most cases this is the desired behavior, because you don't want to spend tons of ink printing the background of a web page. But in some cases you want to print the background color of elements, e.g. bars of a chart. For those elements you need to set the following CSS styles:

-webkit-print-color-adjust: exact; /* Chrome and Safari */
color-adjust: exact; /* Firefox */

Another case is printing of white text. When removing background colors, chances are white text n...