3733 cards
View

Ruby: How to fetch a remote host's TLS certificate

TLS/SSL certificates are often used for HTTPS traffic. Occasionally a service may also use their TLS certificate to support public-key encrypting data (e.g. when it is part of the URI and visible to the user, but contains sensitive information).

Here is how to easily fetch such certificate data.

certificate = Net::HTTP.start('example.com', 443, use_ssl: true) { |http| http.peer_cert }
# => #<OpenSSL::X509::Certificate: subject=#<OpenSSL::X509::Name CN=www.example.org,...>

certificate.public_key
# => #<OpenSSL::PKey::RSA:0x...

Sass partial names must always start with an underscore

Be careful to name any file @imported by SASS with a leading underscore.

SASS files not beginning with an underscore will be rendered on their own, which will fail if they are using variables or mixins defined elsewhere. (For me it broke only in production, which may be due to some settings in SASS-GEM/lib/sass/plugin/rails.rb.)

From the SASS docs:

The underscore lets Sass know that the file is only a partial file and that it should not be generated into a CSS file.

Linked content

Inspecting a live Ruby process

How to get a backtrace from a running Ruby process:

Ruby 2.4+

TL;DR to get the backtrace of a live process (sudo required):

# First, find out the PID of your Ruby process (e.g. passenger-status)
$ sudo gdb -p PID
(gdb) generate-core-file                  # generate a core.PID file for later inspection
(gdb) t a a bt                            # thread apply all backtrace
(gdb) call (void) close(1)                # close...
Repeats

Project management best practices: Standup

If the project team consists of at least 2 members, do a daily standup. It should not take much longer than 15 minutes.

Format

Tell everyone else

  • what you did yesterday
  • what you intend to do today
  • where you might need help or other input
  • if there are new developments everyone needs to know about

A "still working on X, will probably be done today" is totally fine. No need to tell a long story.

If you are out of work, find a new story with the others.

If there are new stories in the backlog, look at them and

  • make sure ev...
Linked content

How to use the Capistrano 2 shell to execute commands on servers

Capistrano 2 brings the shell command which allows you to run commands on your deployment targets.
There is also invoke to run a command directly from your terminal.

Both commands allow running Capistrano tasks or shell commands, and scope to individual machines or machine roles.

Unfortunately Capistrano 3 does not include these commands any more.

cap shell

Basics

First of all, spawn a Capistrano shell (we're using the multistage extension here):

$ cap staging shell

In your "cap" shell you can now run Capistrano ta...

Repeats

Escape a string for transportation in a URL

To safely transport an arbitrary string within a URL, you need to percent-encode characters that have a particular meaning in URLs, like & or =.

If you are using Rails URL helpers like movies_path(:query => ARBITRARY_STRING_HERE), Rails will take care of the encoding for you. If you are building URLs manually, you need to follow this guide.

Ruby

In Ruby, use CGI.escape:

CGI.escape('foo=foo&bar=bar')
=> "foo%3Dfoo%26bar%3Dbar"

Do not ever use URI.encode or ...

Repeats

nvm: Setting a default Node.js version

To set a default Node version for new shells, use nvm alias default <VERSION>:

nvm alias default 1.2.3

I like to use the most recent LTS version as my default:

nvm alias default lts/erbium
Linked content

Guide to String Encoding in Ruby

The linked article has a great explanation how to to deal with string encodings in Ruby. Furthermore you can check out some of our cards about encoding:

Repeats

How to write modular code

Or: How to avoid and refactor spaghetti code

Please note that I tried to keep the examples small. The effects of the methods in this card are of course much more significant with real / more complex code.

What are the benefits of more modular code?

Code is written once but read often (by your future self and other developers who have to understand it in order to make changes for example). With more modular code you reduce the scope of what has to be understood in order to change something. Also, naming things gives you the opportunity t...

How to make a cucumber test work with multiple browser sessions

Imagine you want to write a cucumber test for a user-to-user chat. To do this, you need the test to work with several browser sessions, logged in as separate users, at the same time.

Luckily, Capybara makes this relatively easy:

Scenario:

Scenario: Alice and Bob can chat
  Given Alice, Bob, and a chat session
  When I am signed in as "Alice"
    And I go to the chat
    And I am signed in as "Bob" [session: bob]
    And I go to the chat [session: bob]
    And I send the message "Hello, this is Alice!"
  Then I should see "Hello, this ...

Rails: Rest API post-mortem analysis

This is a personal post-mortem analysis of a project that was mainly build to provide a REST API to mobile clients.

For the API backend we used the following components:

  • Active Model Serializer (AMS) to serializer our Active Record models to JSON.
  • JSON Schema to test the responses of our server.
  • SwaggerUI to document the API.

It worked

The concept worked really good. Here are two points that were extraordinary compared to normal Rails project with many UI components:

  • Having a Rails application, that has no UI components (only...

How to: Validate dynamic attributes / JSON in ActiveRecord

PostgreSQL and ActiveRecord have a good support for storing dynamic attributes (hashes) in columns of type JSONB. But sometimes you are missing some kind of validation or lookup possibility (with plain attributes you can use Active Record's built-in validations and have your schema.rb).

One approach about being more strict with dynamic attributes is to use JSON Schema validations. Here is an example, where a project has the dynamic attributes analytic_stats, that we can use to store analytics from an external measurement tool.

  • A g...
Linked contentRepeats

Generating test images on the fly via JavaScript

When you need test images, instead of using services like lorempixel or placehold.it you may generate test images yourself. You can do this via JavaScript.

Here is an ES6 function that generates a simple SVG image and returns it as a data: URI. All browsers support SVG, and you can easily adjust it yourself.

function svgUri(text) {
  let svg = `
    <svg width="320" height="240" xmlns="http://www.w3.org/2000/svg">
      <rect x="0" y="0" width="320" height="240" style...

Handling duplicate links with Capybara and Cucumber

Sometimes, you might have duplicate links on a page. Trying to click those links will by default cause Capybara to raise an Ambiguous match error.

If you do not care about which of those links are clicked, you can disable this errors by adding the following meta step:

When(/^(.*) \[allow ambiguous\]$/)do |step_text|
  prior_match_strategy = Capybara.match
  Capybara.match = :first
  step(step_text)
ensure
  Capybara.exact = prior_match_strategy
end

Use it with

When I follow "a duplicate link" [allow ambiguous]
Linked content

Structuring Rails applications: the Modular Monorepo Monolith

Root Insurance runs their application as a monolithic Rails application – but they've modularized it inside its repository. Here is their approach in summary:

Strategy

  • Keep all code in a single repository (monorepo)
  • Have a Rails Engine for each logical component instead of writing a single big Rails Application
  • Build database-independent components as gems
  • Thus: gems/ and engines/ directories instead of app/
  • Define a dependency graph of components. It should have few edges.
  • Gems and Engines can be extracted easier once nece...
Linked contentRepeats

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. They're saved into $APPLICATION_ROOT/tmp/capybara

The attached files contain config for cucumber integration and a Then show me a screenshot step.

Including assets for prettier presentation

Make sure to add this to config/environments/test.rb

# Do not generate digests fo...
Linked contentRepeats

Firefox cancels any JavaScript events at a fieldset[disabled]

If you try to listen to events on elements that are nested inside a <fieldset disabled>, Firefox will stop event propagation once the event reaches the fieldset. Chrome and IE/Edge will propagate events.

Since we often bind event listeners to document this can be annoying.

You could solve it by...

Checklist: Using Carrierwave in a Rails project

This checklist should help you to check edge cases that are not part of the default Carrierwave configuration.

This website uses cookies to improve usability and analyze traffic.
Accept or learn more