Git: Show commits that have touched specific text in a file

If you want to find the commits that touched a specific text in a file, use

git log -S 'text in the code' -- path/to/file

If you use tig you may run a similar command to get a navigatable list of affected files:

tig -S'text in the code'

Example

Here is an example, where the move of the convert_number_column_value(value) method in active record is traced (simplified output):

git log -n 1 --pretty=oneline -S 'convert_number_column_value(value)' -- activerecord/lib/active_record/base.rb
ceb33f84933639d3b6...

How Rails chooses error pages (404, 500, ...) for exceptions

When your controller action raises an unhandled exception, Rails will look at the exception's class and choose an appropriate HTTP status code and error page for the response.

For instance, an ActiveRecord::RecordNotFound will cause Rails to render a red "The page you were looking for doesn't exist" with a status code of "404" (not found).

The mapping from exception classes to error types is a hash in Rails.configuration.action_dispatch.rescue_responses. The...

Case sensitivity in PostgreSQL

PostgreSQL, unlike MySQL, treats strings as case sensitive in all circumstances.

This includes

  • comparison with = and LIKE
  • collision detection in unique indexes

Usually this is fine, but some strings (like emails and usernames) should typically be treated as case insensitive.

There are a few workarounds available:

  • use the citext extension (not recommended)
  • use ILIKE instead of LIKE
  • use Postgres' lower() function
  • add an index on lower(email)

Probably th...

Stop animations and network polling when the document tab isn't visible

Is your application doing something expensive every few seconds? Maybe an animated slider that rotates images? Maybe you are updating data over the network every five minutes?

It's a good idea to pause this if the your document tab is not even visible to the user. This saves your user's battery and data plan.

You can ask document.visibilityState whether this tab is visible:

function pulse() {
  if (!document.visibilityState || document.visibilityState...

How to find out what is running on a port on a remote machine

By convention, common protocols use a defined port, like 80 for HTTP or 443 for HTTPS.

You can use nmap to find out what service is running behind a given port, and most often see some details about it. This can be helpful if servers don't offer the services you expect for some ports. If you'd like to see what ports are listing on your local machine, you might want to use netstat instead of nmap.

Note that nmap's service discovery may trigger several requests.

Example

When using nmap, adding the -A switch ...

Building web applications: Beyond the happy path

When building a web application, one is tempted to claim it "done" too early. Make sure you check this list.

Different screen sizes and browsers

Desktops, tablets and mobile devices have all different screen resolutions. Does your design work on each of them?

  • Choose which browsers to support. Make sure the page looks OK, is usable and working in these browsers.
  • Use @media queries to build a responsive design
    • If you do not suppo...

How to force horizontal panel layout for Chrome

Chrome's developer tools automagically choose vertical or horizontal panel layout, based on their width. You can disable that magic.

In the developer tools, klick the cogwheel icon (or press F1 when focusing the dev tools) to open the settings overlay.
Under "Preferences", in the "Appearance" section, find the "Panel layout" option. Set it to your liking.

Alternatively, press Ctrl+Shift+P and search for "panel layout".

Wat?

Vertical means that the DOM tree is next to the styles/etc panel, like so:

![vertical layout example](https:/...

How to organize monkey patches in Ruby on Rails projects

As your Rails project grows, you will accumulate a number of small patches. These will usually fix a bug in a gem, or add a method to core classes.

Instead of putting many files into config/initializers, I recommend to group them by gem in lib/ext:

lib/
  ext/
    factory_girl/
      mixin.rb
    carrierwave/
      change_storage.rb
      fix_cache_ids.rb
      sanitize_filename_characters.rb
    ruby/
      range/
        covers_range.rb
      array/
        dump_to_excel.rb
        xss_aware_join.rb
      enumerable/
    ...

How to Work With Time Zones in Rails

When dealing with time zones in Rails, there is one key fact to keep in mind:

Rails has configurable time zones, while
Ruby is always in the server's time zone

Thus, using Ruby's time API will give you wrong results for different time zones.

"Without" time zones

You can not actually disable time zones, because their existence is a fact. You can, however, tell Rails the only single time zone you'll need is the server's.

config.time_zone = "Berlin" # Local time zone
config.active_record.default_timezone = :loca...

RSpec: Expecting non-primitive objects as method invocation arguments

Expecting a primitive value as an argument to a method invocation is easy:

expect(object).to receive(:foo).with('arg1', 'arg2')

This expectation would be met with this call:

object.foo('arg1', 'arg2')

But what if the argument is expected to be an object with a given set of methods? E.g. this class with #first_name and #last_name methods:

class Person

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end
  
  attr_reader :first_name, :last_name
  
end
``...

Stretching an HTML page to full height

This card existed before, but was outdated due to browser implementation changes. The information below is validated for the current list of browsers we support.


By default your html and body elements are only as high as the actual page content inside their container. If you only have two lines of text in your page, your html and body elements will only be around 40 pixels high, regardless of the size of your browser window.

You might be surprised by this, since setting a background on either html and `body...

Heads up: RSpec's diffs may not tell the truth

RSpec provides a nice diff when certain matchers fail.

Here is an example where this diff is helpful while comparing two hashes:

{a:1}.should match(a:1, b:2)

Failure/Error: {a:1}.should match(a:1, b:2)
  expected {:a=>1} to match {:a=>1, :b=>2}
  Diff:
  @@ -1,3 +1,2 @@
   :a => 1,
  -:b => 2,

Unfortunately, this diff is not as clever as it would need to. RSpec's instance_of matchers will look like errors in the diff (even if they are not), and time objects that differ only in milliseconds won't appear in the ...

Linux: Open a file with the default application

If you are on a Linux shell and want to open a file with whatever default application is configured for that type, this often works:

xdg-open Quote.odt
xdg-open invoice.pdf
xdg-open index.html

Pro Tip

Make an alias so you have a simpler API (like Mac OS): alias open=xdg-open or alias x=xdg-open.

Background

You can choose your "Default applications" via UI in the Ubuntu "Settings" application (gnome-control-center). This is just a very rough setting (e.g. open Photos with Shotwell Viewer).

If a certain file...

Rails route namespacing (in different flavors)

TL;DR There are three dimensions you can control when scoping routes:

scope module: 'module', path: 'url_prefix', as: 'path_helper_name' do
  resources :examples, only: :index
end

as → prefixes path helpers: path_helper_name_examples_path and path_helper_name_examples_url
path → prefixes URL segments: /url_prefix/examples
module → nests the controller: controller Module::ExamplesController, found at app/controllers/module/examples_controller.rb with views in app/views/module/examples/.

These options work with ...

Testing ActiveRecord callbacks with RSpec

Our preferred way of testing ActiveRecord is to simply create/update/destroy the record and then check if the expected behavior has happened.

We used to bend over backwards to avoid touching the database for this. For this we used a lot of stubbing and tricks like it_should_run_callbacks.

Today we would rather make a few database queries than have a fragile test full of stubs.

Example

Let's say your User model creates a first Project on cr...

Testing ActiveRecord validations with RSpec

Validations should be covered by a model's spec.

This card shows how to test an individual validation. This is preferrable to save an entire record and see whether it is invalid.

Recipe for testing any validation

In general any validation test for an attribute :attribute_being_tested looks like this:

  1. Make a model instance (named record below)
  2. Run validations by saying record.validate
  3. Check if record.errors[:attribute_being_tested] contains the expected validation error
  4. Put the attribute into a valid state
  5. Run...

RSpec 3 argument constraints use weak equality

If you expect method calls in RSpec 3, be aware that the argument matchers use very liberal equality rules (more like === instead of ==).

For example:

expect(subject).to receive(:foo).with(MyClass)

subject.foo(MyClass)      # satisfies the expectation
subject.foo(MyClass.new)  # also satisfies the expectation

expect(subject).to receive(:bar).with(/regex/)

subject.bar(/regex/)      # satisfies the expectation
subject.bar('regex')      # also satisfies the expectation

This is usually not an issue, except when your method ...

HTTP 302 redirects for PATCH or DELETE will not redirect with GET

A HTTP 302 Found redirect to PATCH and DELETE requests will be followed with PATCH or DELETE. Redirect responses to GET and POST will be followed with a GET. The Rails form_for helper will use a workaround to send POST requests with a _method param to avoid this issue for PATCH/DELETE.

If you make requests yourself, watch out for the following behavior.

When you make an AJAX request PATCH /foo and the /foo action redirects to /bar, browsers will request PATCH /bar. You probably expected the second requ...

Make Nokogiri use system libxml2

The nokogiri gem provides different packages for several platforms. Each platform-specific variant ships pre-built binaries of libxml2, e.g. x86_64-linux includes binaries for 64bit Linux on Intel/AMD. This significantly speeds up installation of the gem, as Nokogiri no longer needs to compile libxml2.

However, this also means that for each security issue with libxml2, Nokogiri maintainers have to update their pre-built binaries and release a new version of the gem. Then, you need to update and ...

Defining and calling lambdas or procs (Ruby)

Ruby has the class Proc which encapsulates a "block of code". There are 2 "flavors" of Procs:

  • Those with "block semantics", called blocks or confusingly sometimes also procs
  • Those with "method semantics", called lambdas

lambdas

They behave like Ruby method definitions:

  • They are strict about their arguments.
  • return means "exit the lambda"

How to define a lambda

  1. With the lambda keyword

    test = lambda do |arg|
      puts arg
    end
    
  2. With the lambda literal -> (since Ruby 1.9.1)
    ...

Keeping web applications fast

Our applications not only need to be functional, they need to be fast.

But, to quote Donald Knuth,

premature optimization is the root of all evil (or at least most of it) in programming

The reasoning is that you should not waste your time optimizing code where it does not even matter. However, I believe there are some kinds of optimizations you should do right away, because

  • they are either obvious and easy
  • or they are very hard to do optimize later

This is an attempt to list some of those things:

On the server

...

Recommended Git workflow for feature branches

This is a guide on how to effectively use Git when working on a feature branch. It is designed to get out of your way as much as possible while you work, and ensure you end up with clean commits in the end.

We assume you are the only person working on this branch. We also assume the branch has never been "partially" merged into master.

You want to start a feature branch

git checkout master
git checkout -b my-feature-branch
git push -u origin my-feature-branch

You've added code that works ind...

Enumerators in Ruby

Starting with Ruby 1.9, most #each methods can be called without a block, and will return an enumerator. This is what allows you to do things like

['foo', 'bar', 'baz'].each.with_index.collect { |name, index| name * index }
# -> ["", "bar", "bazbaz"]

If you write your own each method, it is useful to follow the same practice, i.e. write a method that

  • calls a given block for all entries
  • returns an enumerator, if no block is given

How to write a canonical each method

To write a m...

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:

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

Do not ever use `URI.en...