3 ways to run Spring (the Rails app preloader) and how to disable it

spring ...

The most obvious way to use spring is to call it explicitly:

spring rails console
spring rake db:migrate

Binstubs

Binstubs are wrapper scripts around executables. In Rails they live inside bin/. If you run spring binstub --all, your binstubs will be using Spring.

bin/rails console
bin/rake db:migrate

bundle exec rails ...

Bundle exec is inconsistent when it comes to spring. Some commands will use it, some won't.

bundle exec rails console # starts Spring...

Fix error: rails console No such file to load -- irb/encoding_aliases.rb (LoadError)

I got this error after upgrading Ruby from 2.4.5 to 2.6.4 when I opened the Rails console - rails server still worked.

Running via Spring preloader in process 14679
Loading development environment (Rails 5.2.2.1)
Traceback (most recent call last):
.../lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/application.rb:175:in 'fork': No such file to load -- irb/encoding_aliases.rb (LoadError)
.../lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/application.rb:175:in 'fork': undefined method 'reject!' for nil:NilClass (NoMethodError)
.../li...

ExceptionNotification gem will only show application backtrace starting on Rails 4

Starting with Rails 4.0, when you get an exception reported via the ExceptionNotification gem, you will only see a very short backtrace with all backtrace lines from gems or ruby libraries missing.

This happens, because the ExceptionNotification gem uses Rails' default backtrace cleaner. To get a full backtrace in exception emails, you can remove the comment from this line in config/initializers/backtrace_silencers.rb:

Rails.backtrace_cleaner.remove_silencers!

Note that this will break the "Application Trace" functionality o...

Rails 3.1 gives you free down migrations

In Rails 3.1+, instead of defining a separate up and down method you can define a single method change:

class AddComparisonFieldsToReport < ActiveRecord::Migration
  def change
    add_column :reports, :compare, :boolean
    update "UPDATE reports SET compare = #{quoted_false}"
    add_column :reports, :compare_start_date, :date
    add_column :reports, :compare_end_date, :date
  end
end

Migrating up works as expected:

b rake db:migrate
==  AddComparisonFieldsToReport: migrating ====================================
-- ad...

Rails + Sidekiq::Web: Configuration for wildcard session cookies

When you're using Sidekiq::Web to monitor the Sidekiq status AND have your session cookie configured to a wildcard domain like .example.com, you need to take an additional step to keep your cookies valid.

Issue

Sidekiq::Web is mounted into your Rails application and will use the Rails session cookie for protection from CSRF attacs. While it somehow figures out the cookie name, it does NOT respect cookie configuration like a custo...

See which Rails applications are being served by your Passenger

To obtain a list of Passenger processes with their application directories and memory usages, you can say

sudo passenger-memory-stats

This will output a list like this:

----- Passenger processes -----
PID    VMSize    Private  Name
-------------------------------
671    112.9 MB  95.5 MB  Rails: /opt/www/project1/current
707    79.4 MB   60.5 MB  Rails: /opt/www/project2/current
1094   88.1 MB   69.3 MB  Rails: /opt/www/project3/current
1260   81.6 MB   62.6 MB  Rails: /opt/www/project4/current
1269   7...

Zeus promises to make rails development faster

I am talking about development speed. When your application starts growing and you start adding gems, it starts to take really long to start up, be it the server, console or just running a single spec.

Zeus is smart, you don’t have to put it in your Gemfile or run it with Bundler, all you need to do is create a JSON config file via zeus init and then start the server zeus start.

After that, you’re ready to go, all you need to do is prefix every command with zeus. That means rails server becomes zeus server, `rails console...

How to get the hostname of the current machine in Rails or a Ruby script

Use Socket.gethostname. So for a machine whose hostname is "happycat", it will look like this:

>> Socket.gethostname
=> "happycat"

That should work right away for your Rails application. For plain Ruby, you first need to do:

require 'socket'

If you don't want to use Socket for some reason, you can still just use the hostname command, at least on non-Windows machines. Keep in mind that you need to remove trailing white space from the result of the system call.

>> `hostname`
=> "happycat\n"
>> `hostname`.stri...

Ruby and Rails deprecation warnings and how to fix them

Add deprecation warnings and their solution or link to available solutions.

Global access to Rake DSL methods is deprecated. Please include Rake::DSL into classes and modules which use the Rake DSL methods.

Open your Rakefile and add the following line above YourApp::Application.load_tasks:

YourApp::Application.class_eval do
  include Rake::DSL
end

Use of ole/file_system is deprecated. Use ole/storage (the file_system api is recommended and enabled by default)...

Upgrading a Rails 3.2 application to Ruby 2.1 is really easy

Upgrading from Ruby 1.8.7 to 2.1.2 took me an hour for a medium-sized application. It involved hardly any changes except

  • removing the occasional monkey patch where I had backported functionality from modern Rubies
  • Migrating from require to require_relative where I loaded RSpec factories in Cucumber's env.rb (the Rails application root is no longer in the load path by default)
  • replacing the old debugger with byebug
  • removing sytem_timer from Gemfile (see [this SO thread](http://stackoverflow.com/questions/7850216/how-to-inst...

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

How to upgrade Cucumber on Rails 3+

  1. Run bundle update cucumber capybara cucumber-rails to update to the newest versions.

  2. Backup your features/support/path.rb to be able to add your own paths again after the cucumber installation script in step 4.

  3. Backup your features/support/env.rb file to be able to reintegrate parts like your blueprints setup:

    ENV["RAILS_ENV"] ||= "cucumber"
    require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
    require 'spec/support/blueprints'
    
  4. Run `$ rails generate cucumber:install --capyba...

Rendering 404s for missing images via Rails routes

When you load a dump for development, records may reference images that are not available on your machine.

Requests to those images may end up on your application, e.g. if a catch-all route is defined that leads to a controller doing some heavy lifting. On pages with lots of missing images, this slows down development response times.

You can fix that by defining a Rails route like this:

if Rails.env.development?
  scope format: true, constraints: { format: /jpg|png|gif/ } do
    get '/*anything', to: proc { [404, {}, ['']] }

...

Caveat when using Rails' new "strict locals" feature

In Rails 7.1 it has become possible to annotate partials with the locals they expect:

# partial _user_name.erb
<%# locals: (user:) %>
<%= user.name %>

# view
<%= render 'user_name' %> <%# this raises an ArgumentError %>

Unfortunately, when some other code in that template raises an ArgumentError (for example an error in the User#name method) you will end up with a confusing stacktrace that looks like you have an error in your render call.

If th...

Rails: Postgres Partial Indexing

PostgreSQL has partial indexes. With a partial index you tell Postgres to only index rows matching a given query.

Some uses cases for a partial index:

  • You want a uniqueness index, but only under some conditions
  • Your table is very large and indexing every row becomes expensive

The linked article shows how to create a partial index with Rails.

Security fixes for Rails 2.3

Last week saw a security issue with rails 2.3 that required a fix. While an official patch was provided, the 2.3 branch is no longer maintained. So we forked it.

(I'm sure there are already 100 other forks doing absolutely the same, but they are not very easily discoverable.)

To use our fork, change the gem "rails"... line in your Gemfile to this:

gem 'rails', :git => 'https://github.com/makandra/rails.git', :branch => '2-3-fixes'

The intent is to make as few changes to the f...

Let a Rails 3 application make a request to itself

Ever wondered how Rails talks to itself in a Cucumber feature? In Rails 3 you can do it like this:

def rack_env(path)
  { "rack.input" => {},
    "PATH_INFO"=>"#{path}",
    "REQUEST_METHOD"=>"GET" }
end

request = rack_env('/users/new')
response = Rails.application.call(request)
status, headers, body = response

puts status # e.g. 200
puts headers.inspect # hash of headers
puts body.body # html of response body

Instead of Rails.application you can also call any Rack application.

Rails 2.3.x sometimes renders localized views with the wrong content type

Under certain (unknown) circumstances, Rails will give localized files an invalid content-type in the Response header. For me, after requesting corporate_information and rendering corporate_information.de.html.haml, Rails sent a content-type of de.html instead of the expected text/html.

There are some discussions on this topic that offer workarounds, but no...

Fix warning "already initialized constant Mocha" with Rails 3.2

You either have an old version of Mocha and an edge version of Rails 3.2, or you have a new version of Mocha and an old version of Rails. The best solution is to update Mocha to the latest version and switch to Rails edge.

If you are using shoulda-matchers or another gem that locks Mocha to an old version, you are out of luck.
More info with many other workarounds that you do not want to use can be found here. A hack to work around this case is to add the following file to lib/mocha/setup.rb:...

Fix warning: Cucumber-rails required outside of env.rb

After installing Bundler 1.1 you will get the following warning when running tests:

WARNING: Cucumber-rails required outside of env.rb. The rest of loading is being defered until env.rb is called.\
To avoid this warning, move 'gem cucumber-rails' under only group :test in your Gemfile

The warning is misleading because it has nothing to do with moving cucumber-rails into a :test group. Instead you need to change your Gemfile to say:

gem 'cucumber-rails', :require => false

MongoMapper for Rails 2 on Ruby 1.9

MongoMapper is a MongoDB adapter for Ruby. We've forked it so it works for Rails 2.3.x applications running on Ruby 1.9. [1]

makandra/mongomapper is based on the "official" rails2 branch [2] which contains commits that were added after 0.8.6 was released. Tests are fully passing on our fork for Ruby 1.8.7, REE, and Ruby 1.9.3.

To use it, add this to your Gemfile:

gem 'mongo_mapper', :git => 'git://github.com/makandra/mongomapper.git', :branch => 'rails2'

...

Riding Rails: Rails 4.0: Final version released!

Rails 4.0 is finally ready after a thorough process of betas and release candidates. It's an amazing new version packed with new goodies and farewells to old features past their expiration date.

Rails ERD – Entity-Relationship Diagrams for Rails

Gem to generate entity relationship diagrams from your Rails 3 ActiveRecord models. The diagram style is pretty and configurable.

How everyone is inserting technical debt in their applications | Plataforma Tecnologia Blog

This means Basecamp migrated from the first Rails release up to the edge one. So how come people say so frequently how hard is to update their applications from Rails 2.1 to Rails 2.2? And the answer is simple: plugins.