How to search through logs on staging or production environments

We generally use multiple application servers (at least two) and you have to search on all of them if you don't know which one handled the request you are looking for.

Rails application logs usually live in /var/www/<project-environment-name>/shared/log.
Web server logs usually live in /var/www/<project-environment-name>/log.

Searching through single logs with grep / zgrep

You can use grep in this directory to only search the latest logs or zgrep to also search older (already zipped) logs. zgrep is used just like grep ...

Partially disable animations for Angular 1.4+

If you use Angular 1.4+ together with Angular Animate, all ng-show, ng-hide, ng-class etc. are animated on default.

If you want only some elements to be animated there are 2 possibilities: Either disable animations globally and only run animations if the element has a certain class or enable animations globally and add a certain class if no animation is wanted.

Option 1: Enable animations only for html elements with class 'animate'

@app.config ['$animateProvider', ($animateProvider) ->
  $animateProvider.classNameFilter(/\ban...

Geordi hints

Reminder of what you can do with Geordi.

Note: If you alias Geordi to something short like g, running commands gets much faster!
Note: You only need to type the first letters of a command to run it, e.g. geordi dep will run the deploy command.

geordi deploy

Guided deployment, including push, merge, switch branches. Does nothing without confirmation.

geordi capistrano

Run something for all Capistrano environments, e.g. geordi cap deploy

geordi setup -t -d staging

When you just clon...

Git stash: Working with old entries

First find the reference for the entry you want through looking at the stash:

$ git stash list
stash@{0}: WIP on feature/foo
stash@{1}: WIP on feature/bar
stash@{2}: WIP on fix/baz

Now you can simply use that reference, but curly braces must be escaped:

git stash pop stash@\{1\}

or quoted:

git stash apply "stash@{1}"

Quick reminder to [not shoot yourself in the foot](https://makandracards.com/makandra/634-use-the-git-stash-withou...

Things you probably didn’t know you could do with Chrome’s Developer Console

Collection of useful tools in the Chrome JavaScript console.

Make the whole page editable

This is not special to Chrome, but still a clever thing:

document.body.contentEditable=true 

Taking time

You can easily measure the time on the console with named timers:

console.time('myTime'); // Start timer
console.timeEnd('myTime'); // End timer and print the time

Reference previously inspected elements (from the Elements panel)

Variables $0, $1, ... $n reference the nth-last inspected Element. $0 ...

An Introduction to Sending HTML Email for Web Developers

A comprehensive introduction to sending HTML emails.

Intro:

HTML email: Two words that, when combined, brings tears to a developer’s eyes. If you’re a web developer, it’s inevitable that coding an email will be a task that gets dropped in your lap at some time in your career, whether you like it or not. Coding HTML email is old school. Think back to 1999, when we called ourselves “webmasters” and used Frontpage, WYSIWYG editors and tables to mark up our websites.

Table of Contents

  • Introduction To Sending Email Link
  • Email List B...

It's OK to put block elements inside an <a> tag

In general, you should not put a block element inside an inline element. So don't do this:

<span>
  <div>text</div>
</span>

The browser will think you wrote invalid HTML by accident, and will sometimes reorder elements silently.

There is one notable exception: It's OK to wrap block elements in a <a> tag in HTML5 (not 4). The spec says:

The a element may be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long ...

Take care of indentation and blank lines when using .erb for plain text emails

Building plain text emails with an .erb template doesn't allow you to indent code like you normally do in HTML mails.

❌ DON'T

<%= 'foo' if bar %>

"\n" if bar is false

"foo\n" if bar is true


<%= nil %>

"\n"


<% if true %>
  <%= 'foo' %>
<% end %>  

" foo"


<%= 'foo' %>

<%= 'bar' %>

"foo\n\nbar\n"

✔️ DO

Write unindented code to get the expected result.

<% if bar %>
<%= 'bar' %>
<% end %>
<%= 'foo' %>
<%= 'bar' %> 
  • Use [Form Models](https://github.com/makandr...

Summarizing heredoc in Ruby and Rails

This card tries to summarize by example the different uses of heredoc.

  • In Ruby << vs. <<- vs. <<~
  • In Rails strip_heredoc vs. squish

strip_heredoc should be used for a text, where you want to preserve newlines. (multi-line -> multi-line)

squish should be used for a text, where you want to squish newlines. (multi-line -> one-line)

Ruby 2.3+

def foo
  bar = <<~TEXT
    line1
    line2
    line3
  TEXT
  puts bar.inspect
end
foo => "line1\nline2\nline3\n"

Read more: [Unindent HEREDOCs in Ruby 2.3](/m...

Debugging cucumber feature with javascript + firefox vnc

TL;DR Debugging problems with javascript errors in cucumber tests is sometimes easier in the browser. Run the test, stop at the problematic point (with Then pause from Spreewald 1.7+) and open VNC for Firefox.

Features:

Giving a presentation with a dual screen layout on linux

When giving a presentation with a projector it is sometimes better to use a dual screen layout instead of a cloned display. If you still want a preview of the projector screen on your primary screen, you can do this:

  1. Install x11vnc and a vnc viewer (e.g. xtightvncviewer).

  2. Connect the projector.

  3. In your system display settings, move the projector to the left or your primary screen (not strictly necessary, but I had weird clipping issues otherwise).

  4. Start a vnc server for your second display with

    x11vnc -clip xinera...
    

Copy to clipboard without flash (clipboard.js)

We used zeroclipboard.js in some of our projects but now we switched to clipboard.js because it does not rely on flash. Flash support of the major browsers has ended.

Some more advantages of clipboard.js:

  • it consists only of a single javascript file, so it does not trigger additional requests with rails
  • it automagically provides user feedback by selecting the text it has copied
  • it provides callbacks for success and error which make it easier to add custom behaviour after copying to the clipboar...

Subclassing module

Yesterday I stumbled across a talk in which the guy mentioned module sub-classing. I was curious what you can do with it and found his blog post with a cool example. It allows you to inject some state into the module you are including elsewhere. Check it out!

class AttributeAccessor < Module
  def initialize(name)
    @name = name
  end

  def included(model)
    super
    define_accessors
  end

  private

  def define_accessors
    ivar = "@#{@name}"
    define_writer(ivar)
    define_reader(ivar)
  end

  def define_writer(ivar)
    ...

Angular with haml: Dynamic html classes

A haml angular 1 template with

.thing(class="is-{{:: item.type }}")

will be compiled (by haml) to

<div class="is-{{:: item.type thing }}"></div>

which is not what you want! It will also crash in angular (unless thing is a valid variable in your angular directive) with Error: [$parse:syntax] Syntax Error: Token 'thing' is an unexpected token at column 11 of the expression [item.type thing]

Solution 1: Use ng-class instead of class

.thing(ng-class='"is-{{ item.type }}"')

**Solution 2: Don't let haml b...

Developer Soft Skills

Knowing when to refactor

Just feeling like refactoring is not a good reason to do it. Make an educated decision: Is the code change worth the effort? Stay straight on track, don't go astray.
Note: Usually, you'd refactor after finishing your story. At times, it might be necessary to refactor up front. But try to keep refactoring out of your current task.

Knowing where to optimize

Things should only be optimized a) when they have settled, i.e. haven't changed for a longer time, and b) when there is a measurable gain from th...

How to "git diff" with a graphical diff tool

If you are fine with the default console diff most of the time but only sometimes want to use an external tool for viewing a diff, you can use git difftool.

E.g. viewing git diff with meld:

git difftool --tool=meld

For each file in the diff you will be asked if you want to view it using meld.

Styling SVGs with CSS only works in certain conditions

SVG is an acronym for "scalable vector graphics". SVGs should be used whenever an image can be described with vector instructions like "draw a line there" or "fill that space" (they're not suited for photographs and the like). Benefits are the MUCH smaller file size and the crisp and sharp rendering at any scale.

It's a simple, old concept brought to the web – half-heartedly. While actually all browsers pretend to support SVG, some barely complex use cases get you beyond common browser support.

In the bas...

Running awstats on a single logfile

AWstats is build to regularly run on webservers. If you want it to build a report once, here is the minimal configuration you need:

Put the following into the awstats config file (look into /etc/awstats/awstats.conf.local or look into /etc/awstats/awstats.conf how to do it on your system):

SiteDomain="yourdomain.de"
DirData="."
DNSLookup=0

Run the following to build a simple HTML page:

awstats -staticlinks -config="yourdomain.de"  -LogFile=your-logfile.log -output > report.html

This might take a second (it will take ...

makandra/gemika: Helpers for testing Ruby gems

We have released a new library Gemika to help test a gem against multiple versions of Ruby, gem dependencies and database types.

Here's what Gemika can give your test's development setup (all features are opt-in):

  • Test one codebase against multiple sets of gem dependency sets (e.g. Rails 4.2, Rails 5.0).
  • Test one codebase against multiple Ruby versions (e.g. Ruby 2.1.8, Ruby 2.3.1).
  • Test one codebase against multiple database types (currently MySQL or PostgreSQL).
  • Compute a matrix of all possib...

VCR fails if the same request is triggered multiple times

Same requests are recorded only once in vcr. Replaying a test fails, if you trigger the same request multiple times. The error message is somehow confusing, as your cassette contains the request:

An HTTP request has been made that VCR does not know how to handle

If you want to allow to match a request multiple times, you need to configure this explicit with allow_playback_repeats: true. Some exa...

How to use Haml in your helpers

You know those helper methods that just render some HTML but look weird because of content_tags all over the place? You could also use Haml instead.

Example

Consider the following helper.

def greeting
  message = ''.html_safe
  message << 'Welcome to '
  message << content_tag(:span, Rails.env, class: 'greeting--location')
  content_tag :div, message, class: 'greeting'
end

That looks clumsy and is hard to read.

Wouldn't it be nicer to say something like this?

def greeting
  render_haml <<-HAML
 ...

Minidusen: Low-tech record filtering with LIKE queries

We have a new gem Minidusen which extracts Dusen's query parsing and LIKE query functionality.

Minidusen can no longer index text in MySQL FULLTEXT columns, which was hardly used and didn't always help performance due to the cost of reindexing.

Minidusen is currently compatible with MySQL, PostgreSQL, Rails 3.2, Rails 4.2 and Rails 5.0.

Basic Usage

Our example will be a simple address book:

class Contact < ActiveRecord::Base
  validates_presence_of :name, :street, :city, :e...

How to tidy up your Git mess

Git is hard: screwing up is easy, and figuring out how to fix your mistakes is fucking impossible. Git documentation has this chicken and egg problem where you can't search for how to get yourself out of a mess, unless you already know the name of the thing you need to know about in order to fix your problem.

So here are some bad situations I've gotten myself into, and how I eventually got myself out of them in plain english*.

Maybe this flowchart may be of help...

Geordi 1.5.1 released

  • Improve geordi cucumber: Only attempt @solo run when the specified files contain the @solo tag, skip @solo run if any filename is passed with a line number (e.g. features/example.feature:3)
  • Improve geordi deploy: Find stages by their prefix (e.g. s -> staging, m -> makandra), bundle if needed, check the selected stage exists
  • Improve geordi server: Takes port as argument (e.g. geordi ser 3001), option --public (-P) starts the server with -b 0.0.0.0 to make it accessible from other machines in the local network, e.g. ...