Search_spinner Cross_grey

Custom loggers in Ruby and Rails

If you need to log to a file you can use Ruby’s Logger class:

log = Logger.new('log/mylog.log')
log.info 'Some information'
log.debug 'Debugging hints'
log.error StandardError.new('Something went wrong')

Logger does a number of things well:

  • Message type (info / debug / error) is logged
  • Log entries are timestamped
  • Writing log output is synchronized between threads
  • Logged errors are printed with full backtraces

If you don’t like the output format, you can define a custom formatter.

I haven’t found a nice way to make `L…

Repeats

Simple database mutex (MySQL lock)

Note: There might an alternative that doesn’t require a database table. We haven’t tested it yet though, while we have been using the technique in this card in production for several years.


If you need to synchronize multiple rails processes, you need some shared resource that can be used as a mutex. One option is to simply use your existing (MySQL) database.

The attached code provides a database-based mutex. You…

Auto-destruct in 57 days

Updated: Get color in the Capistrano output

Card was semantically broken. Now it has two simple instructions.

External content

Communication between collaborating directives in Angular

What if a complicated component comes along that is naturally modeled by multiple directives? This group of directives, as a whole, form a single self contained component. None of directives in the group can stand alone because they only make sense when used together; they collaborate; they are aware of each other and need to communicate with each other.

This post will discuss best practices for managing communication among collaborating directives and illustrate these practices with an example.

How to enable WebGL in Chrome

Check your GPU state on chrome://gpu. If it reads “WebGL: Hardware accelerated” in the first list, you’re set. Else:

  1. Make sure chrome://flags/#disable-webgl is disabled (there should be a link “Enable”)
  2. If that does not help, try to additionally enable chrome://flags/#ignore-gpu-blacklist.
Repeats

Write custom RSpec matchers

There are three ways to define your own RSpec matchers, with increasing complexibility and options:

1) Use RSpec::Matchers.define

RSpec::Matchers.define :be_a_multiple_of do |expected|
  match do |actual|
    actual % expected == 0
  end
  
  # optional
  failure_message_for_should do |actual|
    "expected that #{actual} would be a multiple of #{expected}"
  end
  
  # optional
  failure_message_for_should_not do |actual|
    "expected that #{actual} would not be a multiple of #{expected}"
  end
end

Th…

Dusen (0.5.1) now with "exclude from search"

Dusen (our search gem) is now capable of excluding words, phrases and qualified fields from search.
E.g. search for

  • included -excluded
  • "search this" -"not that"
  • topic:"Yes" topic:-"No"

This will soon also work in makandra cards!

Repeats

Git: Merge a single commit from another branch

This is called “cherry-picking”.

git cherry-pick commit_sha1

Be aware of Cherry picks to production branches!

How to use CSS to rotate text by 90° in IE8 (and modern IEs)

If you want to rotate text, you can use CSS transforms in somewhat modern browsers to rotate the container element.
However, if you need to support IE8, transform is unavailable (if need only IE9 support, ignore the following and use -ms-transform).

Here is a solution that worked for me:

<div class="my-element">Hi!</div>
.my-element {
  display: inline-block;
  transform: rotate(90deg);
  -ms-writing-mode: tb-rl;
  -ms-transform: none;
}

This way, browsers will use CSS transforms when available – w…

Repeats

Some versatile Cucumber steps that operate on DOM elements

Here are some pretty useful steps that haven’t made it into Spreewald yet. These require the auto-mapper for BEM classes in features/support/selectors.rb

When I hover above [selector] element

When /^I hover above (.*) element$/ do |selector|
  page.find(selector_for(selector)).hover
end

Example: When I hover above the album's image element -> triggers a hover event on .album--image

When I…

Repeats

Do not pass an empty array to ActiveRecord.where when using NOT IN

Be careful with the Active Record where method.
When you accidentally pass an empty array to the where method using NOT IN, you probably will not get what you expected:

User.where("id NOT IN (?)", [])

Even though you might expect this to return all records, this actually results in this query:

SELECT `users`.* FROM `users` WHERE (id NOT IN (NULL)) 

This will not return anything.

Angular: Solving "$digest already in progress" error

TL;DR You shouldn’t call $scope.$apply() or $scope.$digest() inside a function that can be invoked by Angular – e.g. in an ngClick.

The linked Stackoverflow answer has a quick overview of techniques to apply changes to a scope. It also explains what might be wrong when you’re getting the error $digest already in progress and gives some information that every Angular developer should know.

Repeats

Detect if a Javascript is running under Selenium WebDriver (with Rails)

Doing this by the book is super-painful.

You might be better of checking against the name of the current Rails environment. To do this, store the environment name in a data-environment of your <body>. E.g., in your application layout:

%body{'data-environment' => Rails.env}

Now you can say in a piece of Javascript:

if ($('body').attr('data-environment') == 'test') {
  // Code that should happen for Se...

Angular: Fixing "Referencing DOM nodes in Angular expressions is disallowed"

Reason

If you are using Coffeescript, it is likely to be the culprit. Since Coffeescript always returns the value of the last expression, it may return DOM nodes:

# coffeescript
scope.focus = ->
  element.focus()

# javascript
scope.focus = function() {
  return element.focus(); // wheee
}

Solution

By adding an explicit return value (e.g. return false), you can Coffeescript from returning a DOM node into Angular.

Repeats

Angular: Understanding how parent and child scope meet on a directive declaration

Say you have the following markup:

{{ someParentVariable = 42 }}

<div child var="{{ someParentVariable }}" ng-click="foo()">
  {{ var }}
</div>

Any angular expression on the child element will be evaluated
before child is initialized. Hence, {{ }} is always evaluated in the
parent scope.
attributes.foo will be "42" inside the child directive
(as a string, because HTML attributes are always strings).

scope: true

If the child directive sets scope:true, a new child scope is
attached to the directive’s element…

Linux: Kill a process matching a partial name

This is useful to kill processes like ruby my-script.rb:

pkill -f my-script.rb

With great power comes great responsibility.

Repeats

How to overwrite and reset constants within Cucumber features

Note: Prefer to not configure your app using global constants. Prefer to set keys in Rails.configuration instead (in application.rb).


In order to save the original value of a constant, set the new value and restore the old value after a scenario was completed, you can use the following helper. It takes care of saving the old constant value, setting the new one without throwing warnings and resets the value with an After hook.

This module also enables you to introduce new global constants.
Since thes…

Angular Style Guide

Opinionated Angular style guide for teams by @john_papa

Not everything in this guide works perfectly for us, but is still a good start.

2751 cards