Some nifty Rails Rake tasks

Did you know?

rake stats # => LOC per controllers, models, helpers; code ratios, and more
rake notes # => collects TODO, FIXME and other Tags from comments and displays them
rake about # (Rails 3+) => Rails, Ruby, Rake, Rack etc. versions, used middlewares, root dir, etc.

String#indent: Know your definitions!

String#indent is not a standard Ruby method. When you use it, be sure to know where this method comes from. Many Gems shamelessly define this method for internal usage, and you'll never know when it may be removed (since it's usually not part of the Gem's API).

Unless you're using Rails 4 (which brings String#indent in ActiveSupport), you'll be best of defining it yourself. This card has it for you.

Gems that define String#indent (incomplete)
----------------------------...

Finding a method name on a Ruby object

Wondering how a specific method on an object is exactly named? You can use Enumerable#grep to detect it in the array of methods.

@user.methods.grep /name/ # => [:name, :first_name, :last_name]

You can also call #private_methods or #public_methods. To find only relevant methods, it is suggested to subtract generic methods like this:

User.methods - Object.methods
User.methods - ActiveRecord::Base.methods
@user.methods - Object.instance_methods
@user.methods - ActiveRecord::Base.instance_methods

How to call overwritten methods of parent classes in Backbone.js

When you are working with Backbone models and inheritance, at some point you want to overwrite inherited methods but call the parent's implementation, too.
In JavaScript, there is no simple "super" method like in Ruby -- so here is how to do it with Backbone.

Example

BaseClass = Backbone.Model.extend({
  initialize: function(options) {
    console.log(options.baseInfo);
  }
});

MyClass = BaseClass.extend({
  initialize: function(options) {
    console.log(options.myInfo);
  }
});

ne...

Ruby number formatting: only show decimals if there are any

Warning: Because of (unclear) rounding issues and missing decimal places (see examples below),
do NOT use this when dealing with money. Use our amount helper instead.


In Ruby, you can easily format strings using % (short for Kernel#sprintf):

'%.2f' % 1.23456 #=> 1.23
'%.2f' % 2 #=> 2.00

However, what if you only want the decimals to be shown if they matter? There is g! It will limit the total number of displayed digits, disregarding...

rbenv: How to switch to another Ruby version

If you want to switch to another ruby versions, you have several options, depending on what you want: Do you want to switch temporarily, per project, or globally?
Here is a short guide.

Unlike RVM, rbenv does not offer a command like rvm use. By default, it respects your project's .ruby-version file.

If you need to change manually, you have several options:

  1. rbenv shell
  2. rbenv local
  3. rbenv global

You probably want rbenv shell.

How to switch your Ruby version temporarily: rbenv shell

In case you only want to...

krisleech/wisper

Publish/subscribe for Ruby classes. Bonus: You do not have to declare events before using them.

How to load only a subset of a massive MySQL dump

I had a huge MySQL dump that took forever (as in: days) to import, while I actually just wanted to have the full database structure with some data to use on my development machine.

After trying several suggestions on how to speed up slow MySQL dump imports (which did not result in any significant improvement), I chose to import just some rows per table to suffice my needs. Since editing the file was not an option, I used a short Ruby script to manage that.

Here is how:

pv huge.dump | ruby -e 'ARGF.each_line { |l| m = l.match(/^INSERT ...

Installing therubyracer and libv8 with Ruby 1.8 on OSX Mavericks

There seems to be no way to use therubyracer -v '0.11.4' and libv8 -v '3.11.8.17' on OS X Mavericks.

However, running bundle update therubyracer worked for me. It installed therubyracer -v '0.12.1' and libv8 -v '3.16.14.3' and I had not side effects.


Log of my attempts to get it working

Probably you got here when bundling failed building native extensions for therubyracer.

The libv8 (3.3.10.4) should have been installed when bundling. Unfortunately it is not building correctly on Mavericks, so the libv8.a f...

How to install older versions of REE with rbenv on Ubuntu 12.04

Rbenv won't compile REE 2011.03 properly on Ubuntu 12.04, failing with an error in tcmalloc.cc.

If you want to keep tcmalloc functionality, you can do it like this:

  1. Open ~/.rbenv/plugins/ruby-build/share/ruby-build/ree-1.8.7-2011.03
  2. Replace the file's contents with those from fgrehm's gist
  3. rbenv install again

You could also try CONFIGURE_OPTS="--no-tcmalloc" rbenv install, but that would disable tcmalloc. Doing that, you might still encounter issues with ossl_ssl.c -- which is ...

The new Modularity 2 syntax

We have released Modularity 2. It has many incompatible changes. See below for a script to migrate your applications automatically.

There is no does method anymore

We now use traits with the vanilla include method:

class Article < ActiveRecord::Base
  include DoesTrashable
end

When your trait has parameters, use square brackets:

class Article < ActiveRecord::Base
  include DoesStripFields[:name, :brand]
end

Note how you ...

Careful with '||=' - it's not 'memoize'

When you do something like this in your code:

def var_value
  @var ||= some_expensive_calculation
end

Be aware that it will run some_expensive_calculation every time you call var_value if some_expensive_calculation returns nil.

This illustrates the problem:

def some_expensive_calculation
  puts "i am off shopping bits!"
  @some_expensive_calculations_result
end

When you set @some_expensive_calculations_result to nil, ||= runs some_expensive_calculation every time....

Opal, A new hope (for Ruby programmers)

Opal is a source to source ruby to javascript compiler, corelib and a runtime implementation that currently passes 3000 rubyspecs w/a reachable goal of passing them all.

Sort a Ruby array with multiple criteria

If you want to sort a Ruby array with a primary, secondary, etc. criterium, use a sort_by that contains a block:

users.sort_by { |user| [user.age, user.name] }

This trick also works with our natural sort method.

How to fix "undefined method `name' for Array" error when running bundled commands on Ruby 1.8.7 + Rails 2.3

On recent/fresh installations of Ruby 1.8.7 you may encounter this error why calling any bundled binary (or just bundle exec):

/home/arne/.rvm/gems/ruby-1.8.7-p374@global/gems/rubygems-bundler-1.4.2/lib/rubygems-bundler/noexec.rb:75:in `setup': undefined method `name' for #<Array:0x7fe04783ef30> (NoMethodError)
  from /home/arne/.rvm/rubies/ruby-1.8.7-p374/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `map'
  ...

Apparently, this is due to bundler (or maybe the rubygems-bundler that RVM supplies by default) no lon...

Auto-coerced virtual attributes with Virtus

We've since created ActiveType which has a restricted subset of Virtus' features. It might be enough for your needs.

We sometimes give our ActiveRecord models virtual attributes for values that don't need to be stored permanently.

When such a virtual attribute should contain integer values you might get unexpected behavior with forms, because every param is a string and you don't get the magic type casting that Rails would give you if it ...

Careful when calling a Ruby block with an array

When a Ruby block or proc takes multiple parameters, and you call it with an Array, Ruby will unexpectedly splat the array elements:

block = proc { |a, b| "a=#{a}, b=#{b}" }
block.call(1, 2)   # "a=1, b=2"
block.call([1, 2]) # "a=1, b=2"

Note that lambdas behave as expected:

block = lambda { |a, b| "a=#{a}, b=#{b}" }
block.call(1, 2)   # "a=1, b=2"
block.call([1, 2]) # ArgumentError: wrong number of arguments (1 for 2)

Embed Font Awesome icons from your CSS

An annoying part of using font icons is that the icons usually need to live in the DOM. This is a step back from the time when we defined raster icons with background-image, in the CSS.

It doesn't have to be that way.

Copy the attached file font-awesome-sass.css.sass to your assets (we recommend /vendor/asset-libs/font-awesome-sass).

You can now use Font Awesome icons from your Sass files:

@import font-awesome-sass

...

Ruby constant lookup: The good, the bad and the ugly

In Ruby, classes and modules are called constants. This card explains how Ruby resolves the meaning of a constant.

The good

E. g. in the following example, Array could mean either Foo::Array or simply Array:

class Foo
  def list
    Array.new
  end
end

What Ruby does here is to see if the name Array makes sense inside of Foo::, and if that fails, resolves it to ::Array (without a namespace).

The bad

This is relevant for old Ruby versions. Ruby 2.5+ removes top-level constant lookup whi...

Ruby: How to measure code execution time in an IRB or Rails console

Modern IRB has time measurement built in.

measure # Enable
measure :off # Disable

Custom

Should your version of IRB not offer this feature, you can measure manually. Paste this method into your console:

def time(&block) puts Benchmark.measure(&block) end

Now time { Some.lengthy_task } will behave similar to the bash time command. Of course you can do much more with the Benchmark object than just putsing it – adapt to your needs.

Howto provide a single page preview for PDF & TXT with carrierwave

Assert rmagick provision ...

Gemfile

gem 'rmagick', '2.13.2' # at this moment the latest stable version

config/initializer/carrierwave.rb

require 'carrierwave/processing/rmagick'

... and define a custom processor

MyUploader.rb

class MyUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick

  def cover
    manipulate! do |frame, index|
      frame if index.zero? # take only the first page of the file
    end
  end

  version :preview do
    process :cover
    process :resize_to_fit => [310,...

Cancelling the ActiveRecord callback chain

Goal Within before_* Within after_*
Cancel later callbacks throw :abort throw :abort
Rollback the transaction throw :abort raise ActiveRecord::Rollback

When a callback raises an error

Exceptions raised in callbacks always rollback the transaction, but only exceptions that are not ActiveRecord::Rollback will bubble up to the caller.

Further readi...

Ruby 1.8: SimpleDelegator is very slow

If you're still working on ruby 1.8, you should know that using SimpleDelegator is often prohibitively slow. I have seen SimpleDelegator.new(myActiveRecordModel) take 50ms+ per instantiation.

The reason is that SimpleDelegator actually loops through all methods of an object and does a define_method. Which is not exactly fast.

To speed up your code, you can often simply replace

class MyUserDecorator < SimpleDelegator
   ...
end

with

class MyUserDecorator < DelegateClass(User)
   ...
end

This...