3651 cards
View
Repeats

Rails: Do not load frameworks you don't need

Rails is split into a large number of (sub-) frameworks.

The most important and central of those are

  • activesupport (extends the Ruby standard library)
  • activerecord / activemodel (ORM for Rails)
  • actionview / actionpack (controller / views)
  • actionmailer (sends mails)

However, there are also some more situational frameworks included, such as

  • actioncable (real time communications using websockets)
  • actionmailbox (receives mails)
  • actiontext (support for WYSIWYG text editor)
  • activejob (background jobs)
  • activestorage (file uplo…

Take care of existing users when upgrading Clearance

When upgrading Clearance, pay attention whether the password hashing strategy might have changed. Old clearance versions (< 1.0) used SHA1-encrypted passwords by default. Current versions default to BCrypt.

If you simply upgrade without taking this into account, users will get a BCrypt::Errors::InvalidHash when trying to sign in. Your tests will not notice this, since they create new users for each scenario.

To fix it, you'll either have to force all users to reset their passwords, or you can allow old users to keep signing in with t…

Known MariaDB version incompatibilities

MariaDB (and MySQL) is released in different versions with different behaviors. For backwards compatibility this can be managed with the sql_mode option.

Following you can find behavior differences which cannot be changed by this option. This can cause a regression in an existing application. There is no workaround available. The application needs to be adapted.

Queries with aggregated date types

For a database instance of MariaDB-10…

Fix for "Rails assets manifest file not found" in Capistrano deploy

If you use webpacker in your Rails application, and you have completely disabled Sprockets, you might get the following error when trying to deploy: Rails assets manifest file not found. This happens inside the deploy:assets:backup_manifest task.

This task is build for Sprockets and does not work with webpacker. Simply skip it, by adding the following line to your config/deploy.rb:

Rake::Task["deploy:assets:backup_manifest"].clear_actions
Repeats

Cucumber pitfall: "Around" does not apply to your "Background" steps

Around will not happen until after a feature's Background has been processed. Use Before and After to avoid that.

Details

Consider this Cucumber feature file:

Feature: Something that needs to be tested

  Background:
    Given a user
      And I sign in        
    
  Scenario: Sign out
    When I sign out
    Then I should see "Signed out"
  
  Scenario: Something else
    # ...

Now, assume you have these step definitions:

Around do
  puts "** Around: before yield"    ...
Linked contentRepeats

Casting ActiveRecord scopes or instances to ActiveType extended model classes

When working with ActiveType you will often find it useful to cast an ActiveRecord instance to its extended ActiveType::Record variant.

Starting with active_type 0.4.0 you can use ActiveType.cast for this:

class User < ActiveRecord::Base
  ...
end

class SignUp < ActiveType::Record[User]
  ...
end

user = User.find(1)
sign_up = ActiveType.cast(user, SignUp)
sign_up.is_a?(SignUp) # => true

This is basically like [ActiveRecord#becomes](http://apidock.com/rails/v4.2.1/ActiveRecord/Pers…

Linked contentRepeats

Linux: Running a single unique instance of command + arguments

run-one is a wrapper script that won't run the given command while another instance of it is running. Is brings several utility commands that offer similar behavior.

```
NAME
run-one - run just one instance at a time of some command and unique set of arguments (useful for cronjobs, eg)

SYNOPSIS
run-one COMMAND [ARGS]

   run-this-one COMMAND [ARGS]

   run-one-constantly COMMAND [ARGS]

   keep-one-running COMMAND [ARGS]

   run-one-until-success COMMAND [ARGS]

   run-one-until-failure COMMAND [ARGS]

Repeats

Controlling how your website appears on social media feeds

When a user shares your content, a snippet with title, image, link and description appears in her timeline. By default social networks will use the window title, the first image, the current URL and some random text snippet for this purpose. This is often not what you want.

Luckily Facebook, Twitter, etc. lets you control how your content appears in the activity streams. They even have agreed on a common format to do this: OpenGraph <meta> tags that go into your HTML's <head>:

<meta property="og:url" content="http://start.makan...
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

Regex: Be careful when trying to match the start and/or end of a text

Ruby has two different ways to match the start and the end of a text:

  • ^ (Start of line) and $ (End of line)
  • \A (Start of string) and \z (End of string)

Most often you want to use \A and \z.

Here is a short example in which we want to validate the content type of a file attachment. Normally we would not expect content_type_1 to be a valid content type with the used regular expression image\/(jpeg|png). But as ^ and $ will match lines, it matches both content_type_1 and content_type_2. Using \A and \z will wo…

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…

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…

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…
This website uses cookies to improve usability and analyze traffic.
Accept or learn more