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
rake aborted! undefined method `task’ in rails 3.0.7
If you are getting this error when you run any rake task in rails 3.0.7:
$ rake rake aborted! undefined method `task' for #MyApp::Application:0x92113b6c
The problem is rake 0.9.0. The simple fix is temporarily downgrade rake in order to avoid it:
$ gem uninstall rake -v 0.9 $ gem install rake -v 0.8.7
Then, edit the Gemfile and add the line:
gem 'rake', '0.8.7'
And run the command:
$ bundle update
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];