ActiveRecord: Order a scope by descending value without writing SQL

Instead of this:

Image.order('images.created_at DESC')

You can write this:

Image.order(created_at: :desc)

Not only do you not have to write SQL, you also get qualified column names (created_at becomes images.created_at) for free.

Multiple order criteria

To add secondary order criteria, use a hash with multiple keys and :asc / :desc values:

Image.order(title: :asc, created_at: :desc)

PostgreSQL: How to change attributes of a timestamp

It's generally not trivial to change a datetime's seconds, minutes, etc in SQL. Here is how it works when speaking PostgreSQL.

Consider you have a timestamp column whose seconds you want to zero:

SELECT born_at FROM users;
       born_at
---------------------
 2015-05-01 13:37:42

You can the TO_CHAR function to convert date or time values into a string, and do your changes there:

SELECT TO_CHAR(born_at, 'YYYY-MM-DD HH24:MI:00') FROM users;
       to_char
---------------------
 2015-05-01 13:37:00

...

Differences between transactions and locking

Web applications can be used by multiple users at the same time. A typical application server like Passenger has multiple worker processes for a single app. In a distributed deployment setup like we use at makandra you will even have multiple application servers, each with their own worker pool.

This means that your code needs to deal with concurrent data access. The two main tools we use to cope with concurrency are database transactions and distributed locks. These two are not interchangeable. You ca...

Slack integration for deployments via Capistrano

You can hook into Slack when using Capistrano for deployment. The slackistrano gem does most of the heavy lifting for you. Its default messages are unobtrusive and can be adjusted easily.

When deploying, it posts to a Slack channel like this:

Example

How to integrate

Integrating Slackistrano with Capistrano 3 is fairly simple.

  1. In your Slack, open menu → A...

Exporting to Excel from Rails without a gem

See this Railscast.

Basically you can simply write views like index.xlsx.erb:

<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
  xmlns:o="urn:schemas-microsoft-com:office:office"
  xmlns:x="urn:schemas-microsoft-com:office:excel"
  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
  xmlns:html="http://www.w3.org/TR/REC-html40">
  <Worksheet ss:Name="Sheet1">
    <Table>
      <Row>
        <Cell><Data ss:Type="String">ID</Data></Ce...

Multiline comments in indented Sass syntax

Write a // and indent every subsequent line by two spaces.

This is great for documenting BEM blocks!

//
  An action button
  ================
  
  Basic usage
  -----------
  
      <a href="/path" class="action">New booking</a>
      <button class="action">Save</a>
      <input type="submit" class="action">Save</a>
  
  Colors
  -------
  
      <a href="/path" class="action is-red">Primary</a>
      <a href="/path" class="action is-grey">Secondary</a>
  
  Small inline buttons
  --------------------
  
      <p>
        Recor...

SQL: Find out number of rows of all tables within a MySQL database

Here you are:

SELECT table_name, table_rows FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'your_database' order by table_rows;

postgres: window functions

Good article about window functions. Also note how they use a postgres feature called common table expressions.

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

How to coordinate distributed work with MySQL's GET_LOCK

The linked article explains how to get a database-wide lock without creating table rows:

This article explains how I replaced file-based methods to ensure only one running instance of a program with MySQL’s GET_LOCK function. The result is mutual exclusivity that works in a distributed environment, and it’s dead simple to implement.

Ruby implementation

An implementation as a Rubygem seems to be [with_advisory_lock](https:...

Using PostgreSQL and jsonb with Ruby on Rails

Postgres 9.4 introduces a new column type: jsonb. json and jsonb columns store data differently, so just compare the two when you want to store JSON data and choose the one that matches your use case best.

Rails 4.2 includes support for jsonb columns, too. The article outlines different ways on how to interact with the serialized object.

An auto-mapper for BEM classes in Cucumber selectors

When you are using the #selector_for helper in Cucumber steps, as e.g. Spreewald does, the following snippet will save you typing. It recognizes a prose BEM-style selector and maps it to the corresponding BEM class.

For a variation on this idea, see An auto-mapper for ARIA labels and BEM classes in Cucumber selectors.

Examples

"the main menu" -> '.main-menu'
"the item box's header" -> '.item-box--header'

Here are some examples of steps (using Spreewald, too):

T...

Rails: Running specific migrations

When running migrations with rake db:migrate, there's the STEP and VERSION parameters that you can pass to nearly all commands.

# Migrate
rake db:migrate
rake db:migrate STEP=2
rake db:migrate VERSION=20080906120000

# Redo
rake db:migrate:redo
rake db:migrate:redo STEP=2
rake db:migrate:redo VERSION=20080906120000

# Rollback (starting from latest migration)
rake db:rollback
rake db:rollback STEP=2

# Run the `down` migration path of a certain migration file
rake db:migrate:down VERSION=20080906120000

Git: How to get a useful diff when renaming files

tldr; Use git diff -M or git diff --find-renames when you've moved a few files around.

Usage

$ git diff --help
  Options:
    -M[<n>], --find-renames[=<n>]
      Detect renames. If n is specified, it is a threshold on the similarity index
       (i.e. amount of addition/deletions compared to the file’s size). For example,
       -M90% means Git should consider a delete/add pair to be a rename if more than
       90% of the file hasn’t changed. Without a % sign, the number is to be read as
       a fraction, with a decimal point...

greckout - a bash script to grep and checkout your git branches

greckout query

This will list all branches matching your query as input options for git checkout

  greckout ar
  
  1) ar/cache-api-keys-1098
  2) ar/add-categories-object-to-tv-show-1382
  3) ...

How to load an SQL dump from a migration

If you want to load an SQL dump from an ActiveRecord migration, you might find this to be harder than you thought. While you can call ActiveRecord::Base.connection.execute(sql) to execute arbitrary SQL commands, the MySQL connection is configured to only accept a single statement per query. If you try to feed it multiple statements, it will die with You have an error in your SQL syntax.

You can work around this by opening a second MySQL connection that does accept multiple statements per call.

Below is an example for a migration that l...

Geordi 1.0 released

Geordi 1.0 features a command line application geordi, that holds most of Geordi's previous commands.

New features

  • command help and usage examples right within geordi (geordi help and geordi help <command>)

  • quick command access: type just the first few letters of a command, e.g. geordi rs or geordi dev[server]

  • command dependencies, e.g. geordi rspec invokes geordi bundle-install (which bundles only if needed)

  • no cluttered /usr/bin, but all commands in one handy tool

  • template for easily adding new...

How to set up database_cleaner for Rails with Cucumber and RSpec

Add gem 'database_cleaner' to your Gemfile. Then:

Cucumber & Rails 3+

# features/support/database_cleaner.rb

DatabaseCleaner.clean_with(:deletion) # clean once, now
DatabaseCleaner.strategy = :transaction
Cucumber::Rails::Database.javascript_strategy = :deletion

Cucumber & Rails 2

The latest available cucumber-rails for Rails 2 automatically uses database_cleaner when cucumber/rails/active_record is required -- but only if transactional fixtures are off. To have database_cleaner work correctly:

  1. Add the ...

Rendering: repaint, reflow/relayout, restyle

Some insight into how browser rendering engines work. The article shows how the way you manipulate styles (and the DOM) can affect rendering performance by forcing the browser to re-paint large portions of the screens, or re-calculate the dimensions of a large subtree of DOM nodes.

Materialized views with Sequel

Sequel is an awesome ORM such as ActiveRecord. The linked article describes how easily you can implement and use materialized views with postgres as your underlying database.

Jasmine: Testing AJAX calls that manipulate the DOM

Here is a Javascript function reloadUsers() that fetches a HTML snippet from the server using AJAX and replaces the current .users container in the DOM:

window.reloadUsers = ->
  $.get('/users').then (html) ->
    $('.users').html(html)

Testing this simple function poses a number of challenges:

  • It only works if there is a <div class="users">...</div> container in the current DOM. Obviously the Jasmine spec runner has no such container.
  • The code requests /users and we want to prevent network interaction in our uni...

Getter and setter functions for JavaScript properties

JavaScript objects can have getter and setter functions that are called when a property is read from or written to.

For example, if you'd like an object that has a virtual person.fullName attribute that dynamically composes person.firstName and person.lastName:

var person = {

  firstName: 'Guybrush',

  lastName: 'Threepwood',

  get fullName() {
    return this.firstName + " " + this.lastName;
  },
  
  set fullName(name) {
    var parts = name.split(" ");
    this.firstName = parts[0];
    this.lastName = parts[1];
  }

};
`...

Taking screenshots in Capybara

Capybara-screenshot can automatically save screenshots and the HTML for failed Capybara tests in Cucumber, RSpec or Minitest.

Requires Capybara-Webkit, Selenium or poltergeist for making screenshots. Screenshots are saved into $APPLICATION_ROOT/tmp/capybara.

Manually saving a page

Additionally you can trigger the same behavior manually from the test using Capybara::Session#save_and_open_page and [...

pgcli - Postgres command line interface

A CLI for working with Postgres databases. Ships with auto-completion and syntax highlighting.