Webmock normalizes arrays in urls

Typhoeus has a different way of representing array params in a get request than RestClient.

Typhoeus: http://example.com/?foo[0]=1&foo[1]=2&foo[2]=3
RestClient: http://example.com/?foo[]=1&foo[]=2&foo[]=3

Webmock normalizes this url when matching to your stubs, so it is always http://example.com/?foo[]=1&foo[]=2&foo[]=3. This might lead to green tests, but in fact crashes in real world. Rack::Utils.build_nested_query might help to build a get re...

Middleman configuration for Rails Developers

Middleman is a static page generator that brings many of the goodies that Rails developers are used to.

Out of the box, Middleman brings Haml, Sass, helpers etc. However, it can be configured to do even better. This card is a list of improvement hints for a Rails developer.

Gemfile

Remove tzinfo-data and wdm unless you're on Windows. Add these gems:

gem 'middleman-livereload'
gem 'middleman-sprockets' # Asset pipeline!

gem 'bootstrap-sass' # If you want to use Bootstrap

gem 'byebug'

gem 'capistrano'
gem 'capistrano-mid...

Capistrano 3: How to deploy when a firewall blocks your git repo

Sometimes, through some firewall or proxy misconfiguration, you might have to deploy to a server that cannot access the git repository.

Solution 1: HTTP Proxy (this is the preferred fix)

SSH can be tunneled over an HTTP Proxy. For example, when the repo is on github, use this:

  1. Install socat

  2. Add a ~/.ssh/config on the target server(s) with permission 0600 and this content:

    Host github.com ssh.github.com
      User git
      Hostname ssh.github.com
      Port 443
      ProxyCommand socat - PROXY:<your proxyhost>:%h:%p,...
    

Quickly printing data in columns on your Ruby console

Dump this method into your Ruby console to quickly print data in columns. This is helpful for e.g. comparing attributes of a set of Rails records.

def tp(objects, *method_names)
  terminal_width = `tput cols`.to_i
  cols = objects.count + 1 # Label column
  col_width = (terminal_width / cols) - 1 # Column spacing

  Array(method_names).map do |method_name|
    cells = objects.map{ |o| o.send(method_name).inspect }
    cells.unshift(method_name)

    puts cells.map{ |cell| cell.to_s.ljust(col_width) }.join ' '
  end

  nil
end

Usag...

Style Guide for Git commit messages

  1. Separate subject from body with a blank line
  2. Limit the subject line to 50 characters (max. 72), include reference (unique story ID) to requirements tracker (Linear in our case)
  3. Capitalize the subject line
  4. Do not end the subject line with a period
  5. Use the imperative mood in the subject line
  6. Wrap the body at 72 characters
  7. Use the body to explain what and why vs. how.

    Tip

    As an alternative, use a commit message that refers to a GitHub issue (fixes #321) or [story ID](https://makandracards.com/makandra/620718-b...

Using ActiveRecord with threads might use more database connections than you think

Database connections are not thread-safe. That's why ActiveRecord uses a separate database connection for each thread.

For instance, the following code uses 3 database connections:

3.times do
  Thread.new do
    User.first # first database access makes a new connection
  end
end

These three connections will remain connected to the database server after the threads terminate. This only affects threads that use ActiveRecord.

You can rely on Rails' various clean-up mechanisms to release connections, as outlined below. This may...

RSpec: Debug flickering test suites with rspec --bisect

In modern default RSpec configurations, your tests are usually run in random order. This helps to detect "flickering" tests that only fail when run in a certain order.

The reason for this are tests that have side effects causing other tests to fail later. The hard part is to find the offending test.

Enter rspec --bisect:

  1. Say you have a flickering test that passes on its own, but you just saw it fail in a full test run. At the top of the RSpec output, you will see a message like Randomized with seed 12345. Take a note of the number....

Howto: Require a gem that is not in Gemfile

In case you want to require a gem, that is not in the Gemfile of you bundle and therefore not in your loadpath, you need to add the path manually and require the gem afterwards.

Expected error

Requiring a gem, that is not in the Gemfile or .gemspec, will cause an LoadError exception:

require 'example_gem' => LoadError: cannot load such file -- example_gem

Adding a gem to the loadpath temporary

  1. You need to install the gem

gem install 'example_gem'

  1. Then you need to require the path where the gem was install...

Storing trees in databases

This card compares patterns to store trees in a relation database like MySQL or PostgreSQL. Implementation examples are for the ActiveRecord ORM used with Ruby on Rails, but the techniques can be implemented in any language or framework.

We will be using this example tree (from the acts_as_nested_set docs):

root
|
+-- Child 1
|   |
|   +-- Child 1.1
|   |
|   +-- Child 1.2
|
+-- ...

How to use Parallel to speed up building the same html partial multiple times (for different data)

The parallel-gem is quite easy to use and can speed up rendering time if you want to render the same partial multiple times (e.g. for rendering long lists of things).
If your parallelized code talks to the database, you should ensure not to leak database connections.

Consider you want to render a list of groups with their members as json. You can use a partial for the rendering of group members, b...

How to disable Chrome's save password bubble for Selenium tests

When filling out forms in Selenium tests, Chrome shows the (usual) bubble, asking to store those credentials.

While the bubble does not interfere with tests, it is annoying when debugging tests. Here are two ways to disable it:

Option 1: prefs

You can set profile preferences to disable the password manager like so:

prefs = {
  'credentials_enable_service' => false,
  'profile.password_manager_enabled' => false
}

Capybara::Selenium::Driver.new(app, browser: :chrome, prefs: prefs)

Sadly, there are no command line s...

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. The reason is that if a browser doe...

How to make http/https requests yourself with nc/telnet/openssl

Sometimes you want/have to send specific http(s) requests. You can do that easy with curl or just write the request yourself.

make a http request with nc

nc example.com 80
GET / HTTP/1.1
Host: example.com
# press enter

make a http request with telnet

telnet example.com 80
GET / HTTP/1.1
Host: example.com
# press enter

make https request with openssl

openssl s_client -connect example.com:443
GET / HTTP/1.1
Host: example.com
# press enter

You can specify more headers if you want:

nc example.c...

Sending errors to sentry from development

For the initial setup or changes in the sentry reporting it might be useful to enabled reporting of sentry in development. Don't commit these changes and prefer to report to the staging environment. As other developers might be confused of these errors try to given them a proper message and delete them afterwards.


  1. Add config.raven_dsn = 'your-dns' in config/environments/development.rb.
  2. Add development to existing environments in the Raven.configure block: config.environments = ['development', 'staging', 'production'].
  3. ...

How to view Image Metadata on the Linux Command Line with ImageMagick

ImageMagick has a command line tool called identify which can read image metadata:

>identify -verbose DSC00136.JPG
Image: DSC00136.JPG
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Class: DirectClass
  Geometry: 5472x3648+0+0
  Resolution: 350x350
  Print size: 15.6343x10.4229
  Units: PixelsPerInch
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    Red:
      min: 0 (0)
      max: 255 (1)
      mean: 11...

Beware: Nested Spreewald patiently blocks are not patient

Note: The behaviour of Spreewald's within step is as described below for version < 1.9.0; For Spreewald >= 1.9.0 it is as described in Solution 1.


When doing integration testing with cucumber and selenium you will often encounter problems with timing - For example if your test runs faster than your application, html elements may not yet be visible when the test looks for them. That's why Spreewald (a collection of cucumber steps) has a concept of doing things patiently, which means a given b...

Generating barcodes with the Barby gem

Barby is a great Ruby gem to generate barcodes of all different sorts.

It includes support for QR codes via rQRCode; if you need to render only QR codes, you may want to use that directly.

Example usage

Generating a barcode is simple:

>> Barby::Code128.new('Hello Universe').to_png
=> "\x89PNG\r\n\u001A..."

Configuration

Barby supports several barcode types and you must require all necessary files explicitly.

For the example a...

Rails: Default generators

This is a visualization of the files that will be generated by some useful rails generators. Invoke a generator from command line via rails generate GENERATOR [args] [options]. List all generators (including rails generators) with rails g -h.

generator model migration controller entry in routes.rb views tests
scaffold
resource ✔ ...

SASS: Defining linear sizes

Just dumping this in case somebody might need it.

When you need a CSS value (a padding, margin, height etc) to shrink/grow proportionally with the parent element, you normally use percentage values. However, if you need specific values at two given widths, you need to turn to linear functions. The mixin below gives you just that.

// Call with two desired values at two different widths.
// Returns a calc() expression that will scale proportionally between those two.
// Example:
//   Spaci...

How to show an ordered crontab

Crontabs are often unordered, especially when generated for an application where you usually group tasks by their domain/scope.

An example crontab might look like this:

# Begin Whenever generated tasks for: project100
MAILTO="log@example.com"
MAILFROM="cron@example.com"

# When server is booting up, ensure Sidekiq is running
@reboot start_sidekiq

23 8 * * * baz
30 * * * * plop
5 8 * * * bar
1 0 * * * foo
# End Whenever generated tasks for: project100

While you can human-parse this one easily, crontabs with several lines are hard ...

Haml: Prevent whitespace from being stripped in production

Disclaimer

This is not an issue in newer versions of HAML (starting with 5.0.0), as the ugly-option was removed so that in development everything is rendered ugly, too.

Problem

When HTML is rendered from HAML in production or staging environment, whitespace is removed to reduce the download size of the resulting pages. Therefore it might happen that whitespace you see in development is missing in production or staging.

Here is an example of two inlined bootstrap buttons in a t...

Running external commands with Open3

There are various ways to run external commands from within Ruby, but the most powerful ones are Open3.capture3 and Open3.popen3. Since those can do almost everything you would possibly need in a clean way, I prefer to simply always use them.

Behind the scenes, Open3 actually just uses Ruby's spawn command, but gives you a much better API.

Open3.capture3

Basic usage is

require 'open3'

stdout_str, error_str, status = Open3.capture3('/some/binary', 'with', 'some', 'args')
if status.success?...

RestClient / Net::HTTP: How to communicate with self-signed or misconfigured HTTPS endpoints

Occasionally, you have to talk to APIs via HTTPS that use a custom certificate or a misconfigured certificate chain (like missing an intermediate certificate).

Using RestClient will then raise RestClient::SSLCertificateNotVerified errors, or when using plain Net::HTTP:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

Here is how to fix that in your application.

Important: Do not disable certificate checks for production. The interwebs are full of people say...

VCR: Inspecting a request

Using VCR to record communication with remote APIs is a great way to stub requests in tests. However, you may still want to look at the request data like the payload your application sent.

Using WebMock, this is simple: Make your request (which will record/play a VCR cassette), then ask WebMock about it:

expect(WebMock).to have_requested(:post, 'http://example.com').with(body: 'yolo')

Easy peasy.

Related cards