marco-polo improves your Rails console prompt

MarcoPolo shows your app name and environment in your console prompt so you don't accidentally break production
Officially supporting IRB (standard rails console) and pry (via pry-rails gem).

Example:

$ rails console
Loading development environment (Rails 4.2.1)
agencyapp(dev)> 

How to enable SSL in development with Passenger standalone

Here is how to start your Rails application to accept both HTTP and HTTPS in development.

  1. gem install passenger

  2. Create a self-signed SSL certificate. Store the generated files in config/passenger-standalone-ssl.

  3. Create a Passengerfile.json at the project root with this content (or save the attached file):

    {
      "ssl": true,
      "ssl_port": 3001,
      "ssl_certificate": "config/passenger-standalone-ssl/server.crt",
    

    ...

List of Helpful RubyMine Shortcuts

Navigation

CTRL + SHIFT + ALT + N

Search for any symbol in your application, like CSS classes, Ruby classes, methods, helpers etc.

CTRL + SHIFT + N

Search for filename in your application (also dependencies)

CTRL + E

Open a list of recently opened files

ALT + POS1

Open a the navigation bar as a context menu. Allows you to quickly navigate between files.

CTRL + G

Go to line

Actions

CTRL + SHIFT + A

:...

Detecting N+1 queries with Bullet

The Bullet gem is designed to help you increase your application's
performance by reducing the number of queries it makes. It will watch
your queries while you develop your application and notify you when
you should add eager loading (N+1 queries), when you're using eager
loading that isn't necessary and when you should use counter cache.

emcien/iso_latte

Sometimes you need to run background jobs that you can't make important guarantees about - they may run out of memory and get killed, or produce segmentation faults, or exit! directly - and you need to be able to clean up after such problems.

IsoLatte is a gem that allows a block of code to be executed in a subprocess. Exceptions get passed back to the parent process through a pipe, and various exit conditions are handled via configurable callbacks.

Savon: Use complex SOAP types as arguments

If a SOAP API expects you to call a remote method with arguments of complex types, Savon lets you manually set the xsi:type attribute like this:

client.call(:rpc_method,
  message: {
    :some_object => {
      :name => 'foo',
      :other => 'bar',
      '@xsi:type' => 'somenamespace:SomeObject'
    }
  }
)

This is roughly equivalent to this in Javaland, where you have magic generated stub code:

SomeObject so = new SomeObject();
so.setName('foo');
so.setOther('bar');
client.rpcMethod(so);

ZenTest "invalid gemspec" / "Illformed requirement"

Today I ran into this:

Invalid gemspec in [/usr/local/rvm/gems/ruby-1.9.3-p194/specifications/ZenTest-4.9.3.gemspec]: Illformed requirement ["< 2.1, >= 1.8"].

You need a newer Rubygems version. Try this: gem update --system 1.8.29

Understanding Ruby Singleton Classes

Good article about ruby singleton classes.

Testing regular expressions visually

Developing complex regular expressions quickly blows my mind. Here are some online regex editors that help you by highlighting matching text and capture groups:

Upgrading from Capistrano 2 to 3

Capistrano 3 is a major rework of the framework and requires several adjustments to your deploy configuration files. The biggest change is that they moved away from their custom DSL and use Rake instead. For connecting with and operating on the servers, they bring a new gem SSHKit which does the heavy lifting. It's SSHKit's DSL that is used anywhere inside the Rake tasks. See #Resources at the bottom for examples.

Step 1: Upgrade guide

For migration from 2 to 3, follow this tutorial: [Capistrano 3 Upgrade Guide](https://semaphorec...

ActiveRecord: How to use ActiveRecord standalone within a Ruby script

Re-creating a complex ActiveRecord scenario quickly without setting up a full-blown Rails app can come in handy e.g. when trying to replicate a presumed bug in ActiveRecord with a small script.

# Based on http://www.jonathanleighton.com/articles/2011/awesome-active-record-bug-reports/ 

# Run this script with `$ ruby my_script.rb`
require 'sqlite3'
require 'active_record'

# Use `binding.pry` anywhere in this script for easy debugging
require 'pry'

# Connect to an in-memory sqlite3 database
ActiveRecord::Base.establish_connection(
  ad...

RubyMine: Scratch files

There are times when you have a chunk of text that you want to do something with, e.g. replace something on it, or quickly edit it.

While you can open your favorite non-RubyMine editor for this, there is also a plugin: Scratch.

It allows RubyMine to open temporary files (actually they are saved, but somewhere inside the plugin's directory) so you don't need to switch to a text editor like gEdit that works differently and may not even offer what you are used to.

Note that RubyMine also offers so...

Ruby bug: Symbolized Strings Break Keyword Arguments in Ruby 2.2

TL;DR Under certain circumstances, dynamically defined symbols may break keyword arguments in Ruby 2.2. This was fixed in Ruby 2.2.3 and 2.3.

Specifically, when

  • there is a method with several keyword arguments and a double-splat argument (e.g. def m(foo: 'bar, option: 'will be lost', **further_options))
  • there is a dynamically created Symbol (e.g. 'culprit'.to_sym) that is created before the method is parsed
  • the method gets called with both the option and a culprit keyword argument

then the `optio...

What Ruby’s ||= (Double Pipe / Or Equals) Really Does

It is a common misunderstanding that all [op]=-operators work the same way, but actually they don't.

||= and &&=

Those are special cases, because the assignment will only happen if the first variable passes the check (false or nil for || and true for &&).

a ||= b   # => a || (a = b)
a &&= b   # => a && (a = b)

But still, if reading a has any side effects, they will take place regardless of to what a resolves.

Other [op]=

Assignment will always take place, no matter the value of a.

Using mime types with send_file

When using send_file (for example for attachments of any kind), make sure your application knows the correct mime types so that all browsers can handle the files. It is much more convenient for users if they can decide to open a file directly instead of having to save it first.

For Rails >= 3.2

Simply put your mime types in config/initializers/mime_types.rb. send_file will take care of everything else.

For Rails < 3.2

Put your mime types in config/initializers/mime_types.rb. Additionally, tell send_file to use them (for ex...

Unfreeze a frozen ActiveRecord

You can freeze any Ruby object to prevent further modification.

If you freeze an ActiveRecord and try to set an attribute you will an error like this:

can't modify frozen hash

This is because ActiveRecord delegates #freeze to its attributes hash.

You can unfreeze most Ruby objects by creating a shallow copy of the frozen object by calling #dup on it:

user = User.find(3)
user.freeze
unfrozen_user = user.dup

Notes for Rails 2 users
-----------------...

RSpec: Tagging examples and example groups

In RSpec you can tag examples or example groups with any tags you like simply by saying

describe ReportCreator, slow: true do
  # ..
end

describe ReportCreator do
  it 'generates reports', slow: true do
    # ...
  end
end

You can then only run examples with these tags.

rspec --tag slow
rspec -t slow

# Using the parallel_tests gem
rake "parallel:spec[,,--tag slow]"

Or you can run all examples except the ones with a certain tag:

rspec --tag ~slow # note the ~
rspec -t ~slow

# Using the parallel_tests gem
r...

Ruby: How to grow or shrink an array to a given size

If you want to grow a Ruby Array, you might find out about #fill but it is not really what you are looking for. [1]
For arrays of unknown size that you want to grow or shrink to a fixed size, you need to define something yourself. Like the following.

Array.class_eval do

  def in_size(expected_size, fill_with = nil)
    sized = self[0, expected_size]
    sized << fill_with while sized.size < expected_size
    sized
  end

end

Use it like this:

>> [1, 2, 3].in_size(5)
=> [1, 2, 3, nil, nil]

...

Rubymine: Code folding

Code folding is a very useful feature to me. It gives me a quick overview over a file and keeps me from scolling like a hamster in its wheel.

Keyboard shortcuts:

Collapse/expand current code block

strg -/+

Collapse/expand the whole file

strg ctrl -/+

When diving into Cucumber features or huge Ruby classes, I usually collapse all and the gradually expand what I need.

Thread-safe collections in Ruby

When using threads, you must make your code thread-safe. This can be done by either locking (mutexes) all data shared between threads, or by only using immutable data structures. Ruby core classes like String or Array are not immutable.

There are several gems providing thread-safe collection classes in Ruby.

concurrent-ruby

The concurrent-ruby gem provides thread-safe versions of Array and Hash:

sa = Concurrent::Array.new # supports standard Array.new forms
sh = Co...

Rails has a built-in slug generator

Today I learned that Ruby on Rails has shipped with a built-in slug generator since Rails 2.2:

> "What Up Dog".parameterize
=> "what-up-dog" 

> "foo/bar".parameterize
=> "foo-bar" 

> "äöüß".parameterize
=> "aouss" 

Also see: Normalize characters in Ruby.

skorks/nesty

Nested exceptions for Ruby:

When you rescue an error and then re-raise your own, you don't have to lose track of what actually occured, you can keep/nest the old error in your own and the stacktrace will reflect the cause of the original error.

This is awesome when you classes convert exception classes. I now always subclass Nesty::NestedStandardError instead of StandardError for my own error classes.

About Exception#cause

Ruby 2.1 has a built-in mechanism with Exception#cause, which serves a similiar purpos...

Differences between transactions and locking

Web applications can be used by multiple users at the same time. A typical application server like Passenger has multiple worker processes for a single app. In a distributed deployment setup like we use at makandra you will even have multiple application servers, each with their own worker pool.

This means that your code needs to deal with concurrent data access. The two main tools we use to cope with concurrency are database transactions and distributed locks. These two are not interchangeable. You ca...