Spreewald 4.3.3 released

Field error steps

Spreewald's The ... field should have an error and The ... field should have the error ... steps now have built-in support for Rails and Bootstrap (v3-v5) error classes. When using Bootstrap, it is no longer necessary to overwrite the steps in your project.

At the same time, support for formtastic has been removed as there were no real use cases. Due to that, no breaking change was introduced, as the amount of users affected by this should be zero (it was neither in the documentation nor tested).

Users may now add...

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

Use a Bash function to alias the rake command to Spring binstubs or "bundle exec" fallback

There are different ways to run rake:

  • On Rails 4.1+ projects, you have Spring and its binstubs which dramatically improve boot-up time for Rake and similar. You need to run bin/rake to use them.
  • On older projects, you want to run "bundle exec rake" to avoid those ugly "already activated rake x.y.z" errors that hit you when different rake versions are installed for your current Ruby.

Here is a solution that gives you a plain rake command which uses a binstubbed bin/rake if available and falls back to bundle exec rake if necessar...

Email validation regex

There is a practical short list for valid/invalid example email addresses - Thanks to Florian L.! The definition for valid emails (RFC 5322) can be unhandy for some reasons, though.

Since Ruby 2.3, Ruby's URI lib provides a built-in email regex URI::MailTo::EMAIL_REGEXP. That's the best solution to work with.

/\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[...

Open a MySQL shell using credentials from database.yml

In order to open a MySQL shell without the need to enter user and password, you can say the following in any Rails 2 project:

script/dbconsole -p

In Rails 3 you can say:

rails dbconsole -p

If you'd like to enter a database for an environment other than development you can say:

script/dbconsole -p staging

Edge Rider: Power tools for ActiveRecord scopes

In our continued quest to extract proven code snippets from makandropedia into tested and upgradable gems, we have released Edge Rider.

Edge Rider was created with two intents:

  1. Provides a number of utility methods to facilitate hardcore work with scopes.
  2. Provide a stable API for working with scopes across multiple versions of Rails, since Rails has a tradition of breaking details of its scope API every other release.

The gem bundles multiple patches and initializers we've been using for hard...

Postgres: How to force database sessions to terminate

If another session is accessing your database you are trying to reset or drop you might have seen the following error:

PG::ObjectInUse: ERROR:  database "foo_development" is being accessed by other users
DETAIL:  There is 1 other session using the database.

This could be the rails server, rubymine and many more. Beside terminating the session connection manually you can also find out the pid and kill the process.

1. rails db
2. SELECT * FROM pg_stat_activity;

datid            | 98359
datname          | foo_developm...

Useful Ruby Pathname method

If you have a Ruby Pathname, you can use the method :/ to append filepaths to it.

With this method, Ruby code can look like this:

Rails.root/"features"/"fixtures"/"picture.jpg"

Alternatively you can use the #join method, which feels less magic:

Rails.root.join('features', 'fixtures', 'picture.jpg')

NoMethodError: undefined method `cache' for Gem:Module

I got this error when running Rails 2.3 tests for Rails LTS. More stacktrace:

NoMethodError: undefined method `cache' for Gem:Module
    /vagrant/rails-2-3-lts-repository/railties/lib/rails_generator/lookup.rb:212:in `each'
    /vagrant/rails-2-3-lts-repository/railties/lib/rails_generator/lookup.rb:146:in `to_a'
    /vagrant/rails-2-3-lts-repository/railties/lib/rails_generator/lookup.rb:146:in `cache'
    /opt/vagrant_ruby/lib/ruby/1.8/fileutils.rb:243:in `inject'
    /vagrant/rails-2-3-lts-repository/railties/l...

Stub a request's IP address in a Cucumber scenario

The solution in this card is based on a stack overflow post by Leventix.

If you need to make request come from a fixed IP address for the duration of a Cucumber scenario, the code below lets you write this:

Given my IP address is 188.174.117.205

Rails 3

Given /^my IP address is "(.*?)"$/ do |ip|
  ActionDispatch::Request.any_instance.stub(:remote_ip).and_return(ip)
end

Rails 2
-----...

How to fix: "rake db:rollback" does not work

When you run rake db:rollback and nothing happens, you are probably missing the latest migration file (or have not migrated yet).

$ rake db:rollback
$ 

If that happens to you, check your migration status.

$ rake db:migrate:status
   up     20160503143434  Create users
   up     20160506134137  Create pages
   up     20160517112656  Migrate pages to page versions
   up     20160518112023  ********** NO FILE **********

When you tell Rails to roll back, it tries to roll back the latest change that was mi...

How to silence "I18n.enforce_available_locales" deprecation warnings

Before Rails 3.2.14, when supplying an invalid locale to I18n, it would fall back to its config.i18n.default_locale (which is :en by default). Eventually, this will be changed to raise an error by default -- for now, it shows a deprecation warning.

Since Rails 3.2.14 and 3.2.15 did not include security updates, you might not have applied them and probably now encounter these deprecation warnings after upgrading to 3.2.16 (or 4.0.2):

[deprecated] I...

When Sass-generated stylesheets print a Encoding::CompatibilityError

We upgraded a Rails 2 application to Rails 3.2 and Ruby 2.1, changed the mysql adapter from mysql to mysql2, but did not activitate the asset pipeline. Instead we used Sass the old-school way (stylesheets in public/sass/*.sass) and relied on stylesheet_link_tag to activate the Sass compiler.

Now all Sass-generated stylesheets inserted the following text into body:before:

Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT

I could get rid of this by removing all generated .css files in `...

MySQL: Do not use "WHERE id IN (SELECT ....)"

Note: This applies specifically to MySQL. In PostgreSQL for example, this is not an issue.

If you care about performance, never use a query like

UPDATE users SET has_message = 1 WHERE users.id IN (SELECT user_id FROM messages)

MySQL does not optimize this and seems to scan the temporary table, which isn't indexed, for every row in the update statement. This applies to other statements than UPDATE as well.

Instead, either use a JOIN like

UPDATE users INNER JOIN messages ON messages.user_id = users.id SET has_message =...

Bash: How to use colors in your tail output

Sometimes it's nice to have some coloring in your logs for better readability. You can output your logs via tail and pipe this through sed to add ANSI color annotations (which your console then interprets).

To print a log (e.g. rails log) and color all lines containing "FATAL" in red and all lines with "INFO" in green:

tail -f /path/to/log | sed --unbuffered -e 's/\(.*INFO.*\)/\o033[32m\1\o033[39m/' -e 's/\(.*FATAL.*\)/\o033[31m\1\o033[39m/'

Here are the ...

Fix: "undefined method `bytesize' for #<Array>"

I believe that when WEBrick has trouble bringing up your Rails application, the WEBrick component that is supposed to print you a pretty error message has a bug and sometimes fails with this message:

"undefined method `bytesize' for #<Array>"

Starting the application in Passenger gave me a stacktrace in log/development.log that pointed to the actual problem.

Possible causes discovered by looking at the logs
-----------------------------------------------------...

Even with bundler your gem order can be significant

Even when you're using bundler, it might be significant in which order your gems are listed in your Gemfile. This can happen when gems are running around calling require or require_dependency on other gems or application classes when loaded (don't do that!).

A known culprit of this is the (otherwise wonderful) resource_controller gem, which requires ApplicationController when loaded. When your ApplicationController requires later-loaded gems when loaded, Rails will not boot.

He...

Aggregated RSpec/Cucumber test coverage with RCov

With defaults, RCov doesn't work the way you how you would like it to. To create a nice test coverage report, copy the attached file to lib/tasks/rcov.rake. After that rake rcov:all will run all RSpec examples and Cucumber features. The report will be written RAILS_ROOT/coverage/index.html.

Here is what the task does in detail:

  • Generates aggregated coverage of both RSpec and Cucumber
  • Works with Rails 2 and Rails 3
  • Reports for app/**/*.rb and nothing else
  • If called with an environment variable IGNORE_SHARED_TRAITS=true it ...

Using StaticMatic for static pages

Update: Staticmatic will not be further developed. They suggest to switch to middleman.


If you need to make a static web page and find yourself missing all your Rails comforts, take a look at StaticMatic.

This works like an extremely stripped down version of Rails, giving you

  • HAML
  • SASS
  • helpers
  • partials

When done, everything is simply compiled to s...

Alternative to #to_a and Array(...)

Note: In Rails 3+ you can use Array.wrap instead of the solution here.

In the past you could use Array(...) or #to_a to turn an object into an array, unless it already is an array:

Array(5) # => [5]
Array([5]) # => [5]

Unfortunately this idiom has issues and it also triggers deprecation warnings like this one:

warning: default `to_a' will be obsolete

For an alternative you can copy the attached file to `config/i...

Fix Rubygems warning: Gem.source_index is deprecated, use Specification

After updating Rubygems you see a wall of deprecation warnings like this:

NOTE: Gem::SourceIndex#add_spec is deprecated, use Specification.add_spec. It will be removed on or after 2011-11-01.
Gem::SourceIndex#add_spec called from /usr/local/lib/site_ruby/1.8/rubygems/source_index.rb:197.

NOTE: Gem::SourceIndex#add_specs is deprecated with no replacement. It will be removed on or after 2011-11-01.
Gem::SourceIndex#spec_dirs= called from /usr/lib/ruby/gems/1.8/gems/bundler-1.0.14/lib/bundler/rubygems_integration.rb:175

...

Stub methods on any instance of a class in Rspec 1 and Rspec 2

RSpec 1 (Rails 2)

With the most recent spec_candy.rb helpers you can say:

User.stub_any_instance(:foo => :bar)
user = User.new
user.foo
# => :bar

RSpec 2 (Rails 3)

RSpec 2 comes with this feature built in:

User.any_instance.stub(:foo => :bar)
user = User.new
user.foo
# => :bar

RSpec 3
-------...

How to change the order of nested forms being rendered (especially blank forms)

Generally for nested forms, a blank form is placed below all other existing object forms. If you would like to change the position of the blank form(s) you can reorder the object's one-to-many association. For example you can put the blank form on top with the following snippet:

actors = movie.actors
actors.build
actors.unshift(actors.pop(1)) # won't work with Rails 4+

Because build_for_form creates new objects and ap...

How to inspect controller filter chains in specs

Sometimes you need to look at the filter chain in specs. You can do it like that on Rails 2:

controller.class.filter_chain.map(&:method)

Note that we need to look at the controller's class since before_filter and after_filter stuff happens on the class level.

Also mind that the above code will give you all filters, both those run before and after an action. You can query before? and after? on the filter objects to scope down to only some of them:

controller.class.filter_chain.select(&:before?).map(&:method)

For Rails 3, ...