How to list all Rails 3 rake tasks
If you run the “classic” rake -T, only the tasks with descriptions will be appear, for instance:
$ rake -T db
Will display something like:
rake db:create # Create the database from config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config) rake db:drop # Drops the database for the current Rails.env (use db:drop:all to drop all databases) rake db:fixtures:load # Load fixtures into the current environment's database. rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false). rake db:migrate:status # Display status of migrations rake db:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n). rake db:schema:dump # Create a db/schema.rb file that can be portably used against any DB supported by AR rake db:schema:load # Load a schema.rb file into the database rake db:seed # Load the seed data from db/seeds.rb rake db:setup # Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first) rake db:structure:dump # Dump the database structure to db/structure.sql. Specify another file with DB_STRUCTURE=db/my_structure.sql rake db:version # Retrieves the current schema version number
But the rake task db:test:prepare is not listed. If you want to list all the tasks, no matter if have a description or not, use this:
$ rake -P
And if you want to avoid the noise, use the following to show the names of all Rake tasks:
$ rake -P | grep rake
Rails 3 :: Not abandon sending mail within ActionMailer action
In ActionMailer (Rails 3) you can’t decide not to send an email. For instance, you have the following mailer:
class FooMailer < ActionMailer::Base
def bar_email
if some_condition
mail(...)
else
# Can I do nothing? No :-(
end
end
end
If you invoke FooMailer.bar_email.deliver!, when same_condition is false you will get the following error:
ArgumentError: A sender (Return-Path, Sender or From) required to send a message
The workaround for that is move the condition to the place where you are making the call to FooMailer.bar_email.deliver!
How to return a real empty response in Rails
I’m building a JSON API using rails. In several places I only need to send a 200 http code, without response body.
So, I used the head method:
head :ok
But this returns a response body with one blank character, this single space body causes the mobile client to fail (parse error). Below the response (notice the Content-Length):
HTTP/1.1 200 OK Server: nginx/0.7.67 Date: Tue, 06 Sep 2011 14:13:55 GMT Content-Type: text/html; charset=utf-8 Connection: keep-alive Piictu_version: 1.0.14 Cache-Control: no-cache Content-Length: 1 X-Ua-Compatible: IE=Edge,chrome=1 X-Runtime: 0.273965
So, I created a render_ok method to use instead of head:
def render_ok response.headers['Cache-Control'] = 'no-cache' render json: '' end
And now the response is:
HTTP/1.1 200 OK Server: nginx/0.7.67 Date: Tue, 06 Sep 2011 16:14:05 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: no-cache Etag: "d41d8cd98f00b204e9800998ecf8427e" Piictu_version: 1.0.14 X-Ua-Compatible: IE=Edge,chrome=1 X-Runtime: 0.224352
Now the Content-Length header is not present :). I use render json: '', because I want the Content-Type to be application/json, but you can use render text: '' too.
Resque :: How to clear old workers from Redis
In a Rails 3 application we’re using resque for background jobs. Because we’re running on heroku, with new deploys sometimes appears “phantom” resque workers in resque-web, this “phantom” workers are old workers that running on a previous EC2 instance that currently is terminated, so the phantom workers really don’t exist but the keys are still in Redis.
The way I clean this phantom workers is:
File: ./lib/resque_ext.rb
module ResqueExt
#
# ResqueExt.unregister_workers_for_host("ec210-250-192-51")
#
def self.unregister_workers_for_host(host)
Resque.workers.select{|worker| worker.id.split(':').first==host}.each(&:unregister_worker)
end
end
BTW the ./config/application.rb file includes the ./lib folder to be autoloadable:
config.autoload_paths += %W(#{config.root}/lib)
Based on this gist
Replacing fixture generation on Rails 3
Because I don’t like fixtures (I use factory_girl), I change my Rails generators to generate factories instead of fixtures
To do this, just add this to your config/application.rb:
config.generators do |g| g.test_framework :test_unit, :fixture_replacement => :factory_girl end
But in my case, because I prefer rspec instead of test_unit, I use this:
config.generators do |g| g.fixture_replacement :factory_girl, :dir => "spec/factories" end
Changing the factories directory from test/factories (default) to spec/factories.
Because I’m using the rspec-rails gem, I don’t have to define the test framework (but I can), so this works too:
config.generators do |g| g.test_framework :rspec g.fixture_replacement :factory_girl, :dir => "spec/factories" end
RSpec with Mongoid
If you are using Mongoid as ORM and RSpec for testing maybe you are interested in use the mongoid-rspec gem.
mongoid-rspec provide several RSpec matchers and macros for Mongoid.
If you are using the new master branch of Mongoid (which is my case), probably you are facing this error when try to run your specs (rake spec):
no such file to load -- mongoid/associations (LoadError)
This is because the new master branch of Mongoid has deleted the file mongoid/associations. You need use the safe_master branch. Or you can try to use this fork of Mongoid-rspec compatible with Mongoid 2.0.0.rc1:
https://github.com/shingara/mongoid-rspec/tree/mongoid-2.0.0.rc1
To do this, just add this gem to your gemfile:
gem 'mongoid-rspec', :git => 'git://github.com/shingara/mongoid-rspec.git',
:branch => 'mongoid-2.0.0.rc1'
Why rails bundler doesn’t install gems inside a group?
As usual I have several gems in bundler groups called :development and :test.
My Gemfile looks like this.
source 'http://rubygems.org' gem 'rails', '3.0.3' gem 'sqlite3-ruby', :require => 'sqlite3' gem 'paperclip' gem 'aws-s3' gem 'rack-cors', :require => 'rack/cors' gem 'will_paginate', '~> 3.0.beta', :require => 'will_paginate' group :test, :development do gem "rack-test", :path => "vendor/gems/rack-test-0.5.7" gem "rspec-rails", "~> 2.4" gem "cucumber-rails", ">= 0.3.2" gem "capybara", "~> 0.4.1.1" gem 'simplecov', '>= 0.3.8', :require => false # Will install simplecov-html as a dependency end gem 'rest-client'
Everything worked fine, but some day when I run the bundle install command, these gems were ignored and it only installs the gems that not belongs to any group.
That happens because doing some tests related to production environment (few days ago) I ran:
bundle install --without development
And bundler remembers that I did this and will automatically repeat this for the next time
bundle install #remembers and includes --without development
To clear the “cache” I just run:
bundle install --without nothing
And now bundler installs all the gems
Errors uploading images from ASIHTTPRequest in iPhone to Rails 3 application hosted on Heroku
We just went through a painful debug session related to erratic timeouts and "Bad content body" errors when we try to upload images from an iPhone application to Rails 3 application hosted on Heroku.
The iPhone application uses ASIHTTPRequest, checking the Google Groups we found that the issues are related to Persistent Connections, the solution that worked for us was:
[request setShouldAttemptPersistentConnection:NO];