3623 cards
View
Repeats

Dealing with I18n::InvalidPluralizationData errors

When localizing model attributes via I18n you may run into errors like this:

I18n::InvalidPluralizationData: translation data { ... } can not be used with :count => 1. key 'one' is missing.

They seem to appear out of the blue and the error message is more confusing than helpful.

TL;DR A model (e.g. Post) is lacking an attribute (e.g. thread) translation.
Fix it by adding a translation for that model's attribute (attributes.post.thread). The error message reveals the (wrongly) located I18n data (from attributes.thread)….

Repeats

A common mistake in validations using regular expressions

You certainly use regular expressions for validating strings, e.g. e-mail addresses by saying

validate :email, :with => /.../

Such regular expressions often look something like the following: /^[\w+\-.]+@[a-z\d\-.]+\.[a-z]+$/i which perfectly matches as expected:

>> "foo.bar-ooops@bar.com".match /^[\w+\-.]+@[a-z\d\-.]+\.[a-z]+$/i
=> #<MatchData "foo.bar-ooops@bar.com">

… and does not match unwanted values:

?> "invalid email@invalid host.com".match /^[\w+\-.]+@[a-z\d\-.]+\.[a-z]+$/i
=> nil

I know that the express…

Linked contentRepeats

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 do |actual|
    "expected that #{actual} would be a multiple of #{expected}"
  end
  
  # optional
  failure_message_when_negated do |actual|
    "expected that #{actual} would not be a multiple of #{expected}"
  end
end

This is automat…

Auto-destruct in 54 days

Gemika 0.4.0 released

We added support to read the include option from the travis.yml file. All combinations defined in the include option are added to the existing matrix. If no matrix exist, these are the only ones that are run.

This change should make it simpler to understand, which Ruby versions are actually run for a specific Gemfile.

Example with matrix

rvm:
  - 2.1.8
  - 2.3.1
gemfile:
  - gemfiles/Gemfile1
  - gemfiles/Gemfile2

matrix:
  include:
    - rvm: 2.6.3
      gemfile: gemfiles/Gemfile3

This will run all these 5 combinations: …

Repeats

Matching unicode characters in a Ruby (1.9+) regexp

On Ruby 1.9+, standard ruby character classes like \w, \d will only match 7-Bit ASCII characters:

"foo" =~ /\w+/   # matches "foo"
"füü" =~ /\w+/   # matches "f", ü is not 7-Bit ASCII

There is a collection of character classes that will match unicode characters. From the documentation:

  • /[[:alnum:]]/ Alphabetic and numeric character
  • /[[:alpha:]]/ Alphabetic character
  • /[[:blank:]]/ Space or tab
  • /[[:cntrl:]]/ Control character
  • /[[:digit:]]/ Digit
  • /[[:graph:]]/ Non-blank character (excludes spaces, co…
Linked contentRepeats

RubyMine users: you should be using bookmarks

RubyMine allows bookmarking lines of code. This is super-helpful when working on a complex problem.
I've been using this feature for a few years now, and so should you! :)

Here are the default Linux/Windows keystrokes. See the documentation for other keybindings.

Add an anonymous bookmark

F11

A gray checkmark will be shown in the gutter on the left.
If you press F11 again on a bookmarked line, the bookmark will be removed.

Add a named bookmark ("mnemonic")

Ctrl

Repeats

When upgrading/downgrading RubyGems and Bundler on a server, you must clear bundled gems

On application servers, gems are usually bundled into the project directory, at a location shared across deployments.

This is usually shared/bundle inside your project's root directory, e.g. /var/www/your-project/shared/bundle/.
If you can't find that, take a look at current/.bundle/config and look for BUNDLE_PATH.

When you are changing the version of RubyGems or Bundler on a system where gems are installed this way, you must wipe that bundle directory in addition to the user and system gems or gems that are already ins…

Linked contentAuto-destruct in 43 days

Updated: Git: Revert one or more commits

Added instructions on how to revert multiple commits at once.

Linked contentRepeats

Ruby regular expression start/end line vs. start/end string

tl;dr: Most often you want to use \A and \z. Be careful when using ^ and $!

^ Start of line
$ End of line

!!("image/jpeg" =~ /^image\/(jpeg|png)$/) => true
!!("image/png" =~ /^image\/(jpeg|png)$/) => true
!!("application/javascript" =~ /^image\/(jpeg|png)$/) => false

!!("application/javascript\nimage/jpeg\nfoo" =~ /^image\/(jpeg|png)$/) => true

\A Start of string
\z End of string

```
!!("image/jpeg" =~ /\Aimage\/(jpeg|png)\z/) => true
!!("image/png" =~ /\Aimage\/(jpeg|png)\z/) => true
!!("application/javascript" =~ /\Aimage…

Repeats

Be very careful with 301 redirects

Browsers support two kinds of redirects:

  • 301 moved permanently
  • 302 moved temporarily

Be very careful with the 301 type. Most browsers seem to cache these redirects forever, unless you set different Cache-Control headers. If you don't have any cache control headers, you can never change them without forcing users to empty their cache.

The only fix is to keep redirecting the user to the correct page, so if you had

/page-1 --301--> /page-2

but you want

/page-1 --301-> /page-3

your only fix is to change it to

Repeats

Ruby: How to use global variables for a conditional debugger

You can share a state in Ruby with global variables. Even if you should avoid them whenever possible, for debugging an application this could be temporary quite handy.

Example:

class User

  after_save { byebug if $debug; nil }

  def lock
   self.locked = true
   save
  end

end

```
Rspec.describe User do

let(:user) { create(:user) }

before do
# Many users are created and saved in this hook, but we don't want the debugger to stop for them
end …

Capistrano: Finding out who deployed which revision of your application and when

Capistrano automatically logs each (successful) deployment into a file on your application servers.

It is located at the root of your server's project folder, i.e. the parent of releases and current, like so:

/var/www/your-project$ ls
current
log
releases
repo
revisions.log  <---  here
shared

Each line in that file contains the deployed branch, commit, release ID, and username (was read from the deploying user's machine):

```
$ tail -n3 revisions.log
Branch master (at da45511bea63002ac2ff002d1692e09d0dd7cb88) deployed as rel…

DOM API for jQuery users

General hints on the DOM

  • the root of the DOM is document
  • custom elements inherit from HTMLElement. They need a - (dash) in their name, e.g. <notification-box>.
  • event listeners don't have event delegation à la .on('click', cssSelector, handler)

Comparison

Action jQuery DOM API equivalent
Find descendant(s) by CSS selector .find(selector) one: `.querySelector(selecto…
Repeats

Unpoly: Automatically show the full better_errors page when Rails raises an error

When an AJAX request raises an exception on the server, Rails will show a minimal error page with only basic information. Because all Unpoly updates work using AJAX requests, you won't get the more detailled better_errors page with the interactive REPL.

Below is an event listener that automatically repeats the request as a full-page load if your development error shows an error page. This means you get…

Repeats

Use Time.current / Date.current / DateTime.current on projects that have a time zone

Basically, you now need to know if your project uses a "real" time zone or :local, and if config.active_record.time_zone_aware_attributes is set to false or not.

  • With time zones configured, always use .current for Time, Date, and DateTime.

    ActiveRecord attributes will be time-zoned, and .current values will be converted properly when written to the database.
    Do not use Time.now and friends. Timezone-less objects will not be converted properly when written to the database.

  • With no/local time zone use Time.now, `…

Repeats

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…

Repeats

Project management best practices: Working with clients in person

When working on a bigger project, the easiest way to improve your work relation with a client or an external product manager, is to make sure you see them in person once in a while.

It makes sense to meet each other when you start working together to establish a relationship and find out what makes them tick.

If you need to discuss a larger package of work, use the opportunity and meet up and discuss it in person.

When you have to discuss something in your daily work, prefer talking to writing, and consider using a webcam.

Restore changes, even from deleted files, with RubyMines "Local History"-Feature

Sometimes, due to git or other "accidents", important files get deleted or overwritten.

At a state when even Ctrl+Z doesn't work anymore, you maybe can rescue your files with RubyMines "Local History"-Feature!

To do this try the following:

  • If the file got deleted, recreate a new empty file with the same name on the exact same place
  • Open that file in the editor
  • Go to RubyMine and click on VCS -> Local History -> Show History
  • In the now open window, you should see all greater changes made to the File, even before it got deleted/temp…
This website uses cookies to improve usability and analyze traffic.
Accept or learn more