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...

How to subscribe to Ruby security updates

Ruby publishes security issues and MRI updates on ruby-lang.org. Unfortunately there is no straight-forward way to subscribe to these updates via e-mail.

I fixed this for me by taking their RSS feed and submitting it to Blogtrottr. Blogtrottr is an RSS-to-email service that sends you an e-mail whenever the feed updates.

Fix „command failed: /usr/bin/wkhtmltopdf ...“ using PDFKit middleware

Ubuntu 12.04 LTS x64, Ruby 1.8.7, Rails 2.13, PDFKit 0.5.4, Phusion Passenger Apache 2

I ran into this, when I started using passenger to deal with the Single Thread Issue which caused my webrick to deadlock when an ActionController::RoutingError (No route matches "...") occurred.

These steps brought me a little further

(1) assert dependencies are installed

 sudo aptitude install openssl build-essential xorg libssl-dev

(2) only for 64bits OS Run one by one the follo...

Ruby: The & operator

After reading, you will know why and how runners.each(&:run) works. Here some tidbits:

& can be quite confusing because it has a different meaning depending on the context in which it's used.

&object is evaluated in the following way:

  • if object is a block, it converts the block into a simple proc.
  • if object is a Proc, it converts the object into a block while preserving the lambda? status of the object.
  • if object is not a Proc, it first calls #to_proc on the object and then converts it into a block.

Installation of therubyracer fails with "undefined method `include_path'"

Today I ran into trouble installing therubyracer on Ruby 1.8. The installation failed with

*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
   ...

Fix "An error occurred while installing debugger-linecache" with Ruby 1.9.3

You're better off using debugger-ruby_core_source:

gem install debugger-ruby_core_source

If you can't do this, try the following.


Here is how to fix the following error when installing the debugger gem fails:

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension

Note: The following example is for a project using Ruby 1.9.3-p448 -- adjust accordingly for your project.

  1. Fetch the source for your Ruby version, if you do not yet have it:

    rvm fetch ruby-1.9.3-p448
    
  2. Install t...

How to not repeat yourself in Cucumber scenarios

It is good programming practice to Don't Repeat Yourself (or DRY). In Ruby on Rails we keep our code DRY by sharing behavior by using inheritance, modules, traits or partials.

When you reuse behavior you want to reuse tests as well. You are probably already reusing examples in unit tests. Unfortunately it is much harder to reuse code when writing integration tests with Cucumber, where you need to...

Geordi: Choose your firefox version for cuc

Geordi 0.16+ supports running selenium tests with project-specific firefox versions.

Just update the gem. It will still default to using the old 5.0.1 firefox. If you want another one, add a file .firefox-version to your project, containing your preferred version.

geordi cucumber will prompt (and guide) you to install the given version. You can delete any old installation sitting in /opt/firefox-for-selenium if you have one.

VCR: Alternative way of mocking remote APIs

If you need to test interaction with a remote API, check out the VCR gem as an alternative to Webmock or stubbing hell.

The idea behind VCR is that is performs real HTTP requests and logs the interaction in a .yml file. When you run the test again, requests and responses are stubbed from the log and the test can run offline.

It's a great way to mock network requests to an external service without going through the pain of log...

PostgreSQL cheat sheet for MySQL lamers

So you're switching to PostgreSQL from MySQL? Here is some help...

General hints on PostgreSQL

  • \? opens the command overview
  • \d lists things: \du lists users, \dt lists tables etc

Command comparison

Description MySQL command PostgreSQL equivalent
Connect to the database mysql -u $USERNAME -p sudo -u postgres psql
Show databases SHOW DATABASES; \l[ist]
Use/Connect to a database named 'some_database' USE some_database; \c some_dat...

mysql2 and older ruby versions

The mysql2 gem in version 0.3.13 might break while compiling on older patch releases of Ruby 1.9.3 within rvm:

*** [err :: server] ruby: symbol lookup error: /path/to/deployment/shared/bundle/ruby/1.9.1/gems/mysql2-0.3.13/lib/mysql2/mysql2.so: undefined symbol: rb_wait_for_single_fd
*** [err :: server] ruby: symbol lookup error: /path/to/deployment/shared/bundle/ruby/1.9.1/gems/mysql2-0.3.13/lib/mysql2/mysql2.so: undefined symbol: rb_wait_for_single_fd

Fixating mysql2 to version 0.3.11 helped.

dusen and edge_rider gems no longer depend on Rails

dusen 0.4.8 and edge_rider 0.2.3 no longer depend on Rails (they still depend on ActiveRecord). That means you can use them e.g. with Sinatra.

.rvmrc deprecated in favor of .ruby-version and .ruby-gemset

Do not use .rvmrc files to specify Ruby version and gemset configuration any longer, it's deprecated and not considered by other Ruby version managers such as rbenv.

If you want to migrate an existing .rvmrc you can use rvm rvmrc to .ruby-version.
Put gemset specification into .ruby-gemset.

Creating the .ruby-version file on your own, just make a file containing e.g.

1.8.7

Attention: Don't clutter other developers rvms with several unecessary ruby patch levels

When you use the rvm command

rvm --ruby-version use 1....

"cannot load such file -- nokogiri/nokogiri" (or any other Gem with native extensions on rvm and Ruby >= 2)

After running bundler / gem install I could not load nokogiri lately. It died with cannot load such file -- nokogiri/nokogiri.
This is not a problem of the gem but is due to a broken native extensions installation routine.

When installing nokogiri manually and with verbose output by using gem install -V nokogiri -v 1.5.6, you can see the problem scrolling by when the native extension is built:

/usr/bin//install -c -m 0755 nokogiri.so /home/thomas/.rvm/gems/ruby-2.0.0-p247/gems/nokogiri-1.5.6/lib/home/thomas/.rvm/rubies/ruby-2.0.0-p...

Use bundle open to open a gem's code in your $EDITOR

bundle open BUNDLED_GEM will open the BUNDLED_GEM's source code in your default editor.

Parallel gem installing using Bundler

Bundler 1.4.0 (still beta) can install gems in parallel, making a run of bundle install much faster.

The "private" modifier does not apply to class methods or define_method

Ruby's private keyword might do a lot less than you think.

"private" does not apply to class methods defined on self

This does not make anything private:

class Foo

  private

  def self.foo
    'foo'
  end
  
end

You need to use private_class_method instead:

class Foo

  def self.foo
    'foo'
  end
  
  private_class_method :foo
  
end

"private" does not apply to define_method

This does not make anythin...