Using state_machine events within a resource_controller

If you need to call a state_machine event and do not want to re-define resource_controller's create method, try this:

create.before do
  object.state_event = :launch_spaceship
end

Kill a dead SSH shell

If a SSH shell dies (from timeout for example), you cannot kill it with the usual CTRL-C or CTRL-Z. Instead, press
[ENTER]~.
(That is ENTER TILDE PERIOD).

Sun Java JVM/JRE on Ubuntu Linux

Note that you should disable the Java plug-in in your browsers after installation.

Ubuntu >= 12.04

Java 11

sudo apt install openjdk-11-jre-headless

Java 10

sudo add-apt-repository ppa:linuxuprising/java
sudo apt-get update
sudo apt-get install oracle-java10-installer

Java 8

You probably want to get rid of OpenJDK (which is installed by default and leads to bad RubyMine performance):

...

Reload the page in your Cucumber features

Both these approaches will keep your GET parameters -- and will only work for GET requests.

  • Capybara:

    When /^I reload the page$/ do
      visit [ current_path, page.driver.request.env['QUERY_STRING'] ].reject(&:blank?).join('?')
    end
    
  • Webrat:

    When /^I reload the page$/ do
      visit url_for(request.params)
    end
    

For a step that distinguishes between drivers (Selenium, Rack::Test, Culerity), check [n4k3d.com](http://n4k3d.com/blog/2011/02/02/reloading-the-page-in-cucumber-with-capybara-and-seleniu...

Replace substrings in Cucumber step argument transforms

Cucumber step argument transforms can be a powerful way to make your steps more flexible.

Note however that if your transform only matches a substring (no ^ and $ markers at the beginning and end), you are still expected to return a replacement for the whole string that was piped through the transform. If you don't do that, you will truncate that string and possibly make the calling step match where it should not.

Let's say you want a transform that replaces subs...

The WordCount Simulation

So this is the simulation that I use in my Agile Testing class, as well as in other contexts where I want to teach lessons about increasing Agility. The mechanics of the simulation itself are very general: the simulation models the organization of a software company. It just happens to work really well for making Agile concepts very visible, and visceral.

RSpec's context method is broken

RSpec's context (which is basically an alias for describe) takes over your whole application. No object may have its own context method, or you will always receive errors like

"No description supplied for example group declared on ~/project/app/..."

The easiest workarounds:

  • do not name any method context
  • use describe instead of context in your specs, and put this into your spec_helper.rb:\
    Spec::DSL::Main.class_eval do
    if method_defined? :context
    undef :context
    end
    end

Places where cron jobs can hide

  1. In /etc/crontab
  2. In /etc/cron.d/*
  3. In /etc/cron.hourly/*
  4. In /etc/cron.daily/*
  5. In /etc/cron.weekly/*
  6. In /etc/cron.monthly/*
  7. In the personal crontab of any user. This is a magic file you can view with crontab -l and edit with crontab -e. You'll need to su to the respective user to view or edit her crontab.

Delete from joined MySQL tables

When you need to delete rows from a table, and the delete conditions require a joined table, MySQL needs to know which table you want to delete from.

Let's say that Post belongs_to :author. In order to delete all posts from the author named "Eric", write

DELETE posts FROM posts LEFT JOIN authors ON posts.author_id = authors.id WHERE authors.name = 'Eric'

Notice the additional "posts" between DELETE and FROM.

Fixing Web Fonts, A Case Study

Some web fonts with bad hinting can be fixed by applying auto-hinting with Font Squirrel.

Save ActiveRecord models without callbacks or validations (in Rails 2 and Rails 3)

Rails 2

You can use

record.send(:update_without_callbacks)

or

record.send(:create_without_callbacks)

This can be used as a lightweight alternative to machinist's make or FactoryGirl's create, when you just need objects in the database but don't care about any callbacks or validations. Note that create_without_callbacks does not return the object, so you might want to do

record = Record.new.tap(&:create_without_callbacks)

Rails 3

Rails 3 no longer comes with update_without_callbacks or `crea...

Fix permissions of temporary RTeX files (which are group and world-readable)

We use RTeX for PDF exports.
While converting LaTeX to PDF, RTeX opens a temporary file which has problematic permissions: Both group and world can read those files.

Although the temp files should go away they sometimes live longer than one would expect.
We patched RTeX to fix this (and have more secure permissions). Place the code below into config/initializers/rtex.rb

Use Sass without Rails

You don't need a Rails application to use Sass. Even when you're working on a static site you can generate your CSS through Sass.

  • Install Sass with sudo gem install haml
  • Create a folder sass in the folder, that stores your stylesheets, e.g. mkdir css/sass
  • In a separate terminal window, run sass --watch css/sass:css. This will watch your sass files for changes and rewrite stylesheets as required.

This even works on Windows.

Note about your .gitignore

You might want to change our [typical .gitignor...

Recent RSpec features you might not know about

With its you can switch the subject of an example to a method value of the current subject:

describe Array do
  its(:length) { should == 0 }
end

stub_chain is the tie to go along with should_receive_chain's tux:

object.stub_chain(:first, :second, :third).and_return(:this)

You can restore the original implementation of stubbed methods with unstub:

object.stub(:foo => 'bar')
# ...
object.unstub(:foo)

In recent RSpecs ...

A quick guide to pull requests

It’s pretty common for projects hosted on GitHub to receive “pull requests”: requests from people who have cloned your project, made a modification to it and then asking you to merge their changes back into the main project.

There are a lot of ways you can handle these pull requests, here are some of them.

Adding Stroke to Web Text

Because they are vector, it would make sense if we could do things that other vector programs (e.g. Adobe Illustrator) can do with vector text, like draw a stroke around the individual characters. Well, we can! At least in WebKit

Check that a text field is empty with Cucumber

This will not work (it always passes):

Then the "Title" field should contain ""

The value is turned into a regular expression, and an empty regular expression matches any string!

Do this instead for Capybara:

Then the "Title" field should contain "^$"

And do this step for Webrat:

Then /^the "([^"]*)" field should( not)? be empty$/ do |field, negate|
  expectation = negate ? :should_not : :should
  field_labeled(field).value.send(expectation, be_blank)
end

Define an array condition that selects on dynamic columns

For some reason you want to define a find condition in array form. And in that condition both column name and value are coming from user input and need to be sanitized.

Unfortunately this works in SQLite but does not in MySQL:

named_scope :filter, lambda { |attribute, value|
  { :conditions => [ 'articles.? = ?', attribute, value ] }
}

The solution is to use [sanitize_sql_array](http://apidock.com/rails/ActiveRecord/Base/sa...

Run a rake task in all environments

Use like this:

power-rake db:migrate VERSION=20100913132321

By default the environments development, test, cucumber and performance are considered. The script will not run rake on a production or staging environment.


This script is part of our geordi gem on github.

Run a single example group in RSpec

To only run a single describe/context block in a long spec, you can say

spec spec/models/note_spec.rb:545

... where the describe block starts at line 545.

Note: This will only run examples that are direct children of this block, not descendants further down (when nesting describe/context blocks).

You may also pass the line of an it block to run this exact one.

Ruby: How to collect a Hash from an Array

There are many different methods that allow mapping an Array to a Hash in Ruby.

Array#to_h with a block (Ruby 2.6+)

You can call an array with a block that is called with each element. The block must return a [key, value] tuple.

This is useful if both the hash key and value can be derived from each array element:

users = User.all
user_names_by_id = users.to_h { |user| [user.id, user.name] }
{
  1 => "Alice",
  2 => "Bob"
}

Array#to_h on an array of key/value tuples (Ruby 2.1+)

Converts an Array ...

Find files modified since a given timestamp

If you need to find all files inside a directory that were modified in the last 24 hours you can do this:

find . -mtime 1

You can also refer to another file's timestamp like this:

find . -cnewer other_file

This can be used to check against a specific timestamp, too. This is how you check for all files modified today (since 00:00):

touch -t `date +%m%d0000` /tmp/$$
find . -cnewer /tmp/$$

Note that $$ returns the current bash's PID so you will get some file like /tmp/12345 that stays the same for the current shell. This...

Create a valid RSS feed in Rails

This will show you how to create a RSS feed that the Feed Validator considers valid.

Note that RSS is a poorly specified format. Consider using the Atom builder to make an Atom feed instead. Write a note here if you do.

  1. Controller

Create a FeedsController to host the RSS feed. Such a controller is also useful to host other data feeds that tend to gather over the lifetime of an application, e.g. sitemap.xml.:

class...