![]() |
| It's time for all Ruby developers to confront their worst fear... |
One of the scariest moments in the life of a Ruby developer is seeing that dreaded message appear as you try to install a new gem: Building native extensions. This could take a while…. As the console output suddenly hangs, you feel a horrible, sinking sensation of fear in your stomach: something truly bad is about to happen! Then your worse nightmare comes true: in the console you get: ERROR: Failed to build gem native extension. Now you’re condemned to spending hours googling for obscure compiler flags, environment settings or Linux package info – and not doing Ruby development.
For years I’ve been nervous installing gems that contained native extensions because I wasn’t familiar with the gem extension build process, and had no idea where to begin when something went wrong. Today I’m going to confront my own worst fears – and yours – by taking a closer look at what “Building native extensions” actually means…
Check out "Akash" - World's cheapest tablet. It is unabashedly optimized for cost. To be priced at $35 a piece (subsidized by Govt of India) for educational institutes and $60 a piece for retail sale.
Aakash Tablet from Venturebeat on Vimeo.
Specifications
“When everything seems to be going against you, remember that the airplane takes off against the wind not with it”
- ~Henry Ford
I am thrilled that two of my submissions got accepted for presenting at Agile 2012. I am giving two experience reports:
Bengaluru.. here I come.
“Perhaps imagination is only intelligence having fun.”
- ~George Scialabba
I spent my first afternoon in Austin like this.
But before I lounged by the pool, I needed a bit of fuel. Nick, Louisa and I headed to 24 Diner (Home of the chicken and waffles Nick ordered back in March, remember?), where I ordered their veggie burger. It. Was. Awesome. Full of beets for a great texture and topped with arugula, roasted tomatoes, goat cheese and an egg.
Highly recommended.
We usually respond some of the known formats in Rails Application like HTML, XML, JavaScript, RSS and some custom. Have you tried to use your own custom format for your Rails Application? Yes you can use your custom format in Rails Application. Here showing a simple Rails Application with responding custom formats. Get a new [...]
When developing email functionality you don’t want to send real emails to real people before in production. At the same time you need to send them to ensure they are formatted correctly and contain the proper information. You can (and should) write integration tests to verify this but that helps developers gain confidence, what can we do to show non-technical stakeholders that it all works?
Today I’m going to show you how to use Ryan Bates’ letter_opener gem to let you preview your emails without actually sending them. Ryan of course does the always awesome RailsCasts.
Let’s think about the different Rails environments and how we want them to behave with email.
Looking at this, Rails works really well for test with ActionMailer’s :test delivery method that stores the emails in the ActionMailer::Base.deliveries array so you can then use email_spec to write your specs. Production is also covered as long as you give it your mail server configuration. That leaves development and staging which look identical but we’ll see that they are slightly different. I’ll spend the rest of this article talking about how letter_opener lets us do what we want in these environments.
Let’s imagine we are working on a new startup in stealth mode. We want to generate buzz and prepare for a beta launch. We’re hiding the fact its all vaporware with a splashy homepage where people can request an invitation to the beta and it sends a “thanks for your interest” email. Lastly, we want to test it in development and staging.
Here’s a live demo at http://awesome-site-staging.heroku.com/ if you want to dive in and start clicking.
After you request an invitation it shows a page like this

When you fill in your email and click the Request Invitation button, our controller uses a mailer to create and deliver the email.
class InvitesController < ApplicationController
def create
@invite = Invite.new(params[:invite])
@invite.save
InviteMailer.invite_requested(@invite).deliver
redirect_to root_path, :notice => "Thanks for your interest #{@invite.email}. You will hear from us soon."
end
end
The only way to tell whether the email worked is to scroll through the development.log until you see something like this
Sent mail to alex@alexrothenberg.com (20ms)
Date: Fri, 21 Oct 2011 15:09:16 -0400
From: admin@newstartup.com
To: alex@alexrothenberg.com
Message-ID: <4ea1c35cc3d5b_6693830916bc43754@Alex-Rothenbergs-MacBook-Pro.local.mail>
Subject: Invite requested
...
We have received your request to be invited into our awesome site. We'll let you know as soon as its available.
Please check back at http://awesome-site.heroku.com
You must be very excited!
Thanks
An Awesome New Startup
Ok if you’re a developer and you enjoy reading log files but letter_opener lets us do better.
Letter_opener provides us with a UI so we can view the emails right in our browser. It’s super easy to add this gem and I’ll just copy the instructions from its README
Preview email in the browser instead of sending it. This means you do not need to set up email delivery in your development environment, and you no longer need to worry about accidentally sending a test email to someone else’s address
Rails Setup
First add the gem to your development environment and run the bundle command to install it.
gem "letter_opener", :group => :developmentThen set the delivery method in config/environments/development.rb
config.action_mailer.delivery_method = :letter_openerNow any email will pop up in your browser instead of being sent. The messages are stored in tmp/letter_opener.
Once we’ve done that what happens when we use the site to request an invitation? A new tab opens up with the email right there. Now as a user we can tell it’s correct and any non-technical people on the team can feel their confidence rise.

Rails goes through the standard flow to create the mail object and when it’s ready to deliver the message it calls letter_opener’s deliver! method because we registered letter_opener as the action_mailer.delivery_method. Letter_opener saves the email to your file system as an html file then uses launchy to open it in a browser using the file:// protocol.
There will be a couple of problems once we move onto a server which brings us to staging.
If you’re like me you probably have a staging environment where you or your stakeholders can validate your app before releasing it to production and your end users. There are two aspects of this environment that wont work with letter_opener the way it did in development
I had to make some changes to letter_opener to support this kind of server environment. The fork is available at https://github.com/alexrothenberg/letter_opener/tree/on_a_server and I’ll update the article if my pull requests are merged back in.
We need to make a few changes to our application.
1 - Update our Gemfile to use the fork from github
gem 'letter_opener', :git => "git://github.com/alexrothenberg/letter_opener.git", :branch => "on_a_server"
2 - Add a debugging UI link so users can get to the “preview emails” page in something like layouts/application.html.haml
= link_to 'Preview Emails', letter_opener_letters_path if Rails.env.staging?
3 - If you cannot write to the filesystem let letter_opener know in your config/environments/staging.rb
config.action_mailer.delivery_method = :letter_opener
LetterOpener.cannot_write_to_file_system!
Now we can see it all in action.
First, we request an invite.

Then, we click the link “view the Emails that users would have received” link at the bottom and see an “inbox” of everything the app sent.

Fincally clicking one message lets us preview it just as we did in devellopment

We are able to run on heroku without writing to the file system by using the FakeFS gem which simulates the filesystem in memory. FakeFS is designed to be used for testing and one caveat to be aware of is that your old emails will disappear if heroku recycles your dyno due to inactivity.
I hope you think letter_opener is useful and give it a try the next time you need to send email. Remember here’s a live demo at http://awesome-site-staging.heroku.com/ of the site we’ve been talking about here.
When developing email functionality you don’t want to send real emails to real people before in production. At the same time you need to send them to ensure they are formatted correctly and contain the proper information. You can (and should) write integration tests to verify this but that helps developers gain confidence, what can we do to show non-technical stakeholders that it all works?
Today I’m going to show you how to use Ryan Bates’ letter_opener gem to let you preview your emails without actually sending them. Ryan of course does the always awesome RailsCasts.
Let’s think about the different Rails environments and how we want them to behave with email.
Looking at this, Rails works really well for test with ActionMailer’s :test delivery method that stores the emails in the ActionMailer::Base.deliveries array so you can then use email_spec to write your specs. Production is also covered as long as you give it your mail server configuration. That leaves development and staging which look identical but we’ll see that they are slightly different. I’ll spend the rest of this article talking about how letter_opener lets us do what we want in these environments.
Let’s imagine we are working on a new startup in stealth mode. We want to generate buzz and prepare for a beta launch. We’re hiding the fact its all vaporware with a splashy homepage where people can request an invitation to the beta and it sends a “thanks for your interest” email. Lastly, we want to test it in development and staging.
Here’s a live demo at http://awesome-site-staging.heroku.com/ if you want to dive in and start clicking.
After you request an invitation it shows a page like this

When you fill in your email and click the Request Invitation button, our controller uses a mailer to create and deliver the email.
class InvitesController < ApplicationController
def create
@invite = Invite.new(params[:invite])
@invite.save
InviteMailer.invite_requested(@invite).deliver
redirect_to root_path, :notice => "Thanks for your interest #{@invite.email}. You will hear from us soon."
end
end
The only way to tell whether the email worked is to scroll through the development.log until you see something like this
Sent mail to alex@alexrothenberg.com (20ms)
Date: Fri, 21 Oct 2011 15:09:16 -0400
From: admin@newstartup.com
To: alex@alexrothenberg.com
Message-ID: <4ea1c35cc3d5b_6693830916bc43754@Alex-Rothenbergs-MacBook-Pro.local.mail>
Subject: Invite requested
...
We have received your request to be invited into our awesome site. We'll let you know as soon as its available.
Please check back at http://awesome-site.heroku.com
You must be very excited!
Thanks
An Awesome New Startup
Ok if you’re a developer and you enjoy reading log files but letter_opener lets us do better.
Letter_opener provides us with a UI so we can view the emails right in our browser. It’s super easy to add this gem and I’ll just copy the instructions from its README
Preview email in the browser instead of sending it. This means you do not need to set up email delivery in your development environment, and you no longer need to worry about accidentally sending a test email to someone else’s address
Rails Setup
First add the gem to your development environment and run the bundle command to install it.
gem "letter_opener", :group => :developmentThen set the delivery method in config/environments/development.rb
config.action_mailer.delivery_method = :letter_openerNow any email will pop up in your browser instead of being sent. The messages are stored in tmp/letter_opener.
Once we’ve done that what happens when we use the site to request an invitation? A new tab opens up with the email right there. Now as a user we can tell it’s correct and any non-technical people on the team can feel their confidence rise.

Rails goes through the standard flow to create the mail object and when it’s ready to deliver the message it calls letter_opener’s deliver! method because we registered letter_opener as the action_mailer.delivery_method. Letter_opener saves the email to your file system as an html file then uses launchy to open it in a browser using the file:// protocol.
There will be a couple of problems once we move onto a server which brings us to staging.
If you’re like me you probably have a staging environment where you or your stakeholders can validate your app before releasing it to production and your end users. There are two aspects of this environment that wont work with letter_opener the way it did in development
I had to make some changes to letter_opener to support this kind of server environment. The fork is available at https://github.com/alexrothenberg/letter_opener/tree/on_a_server and I’ll update the article if my pull requests are merged back in.
We need to make a few changes to our application.
1 - Update our Gemfile to use the fork from github
gem 'letter_opener', :git => "git://github.com/alexrothenberg/letter_opener.git", :branch => "on_a_server"
2 - Add a debugging UI link so users can get to the “preview emails” page in something like layouts/application.html.haml
= link_to 'Preview Emails', letter_opener_letters_path if Rails.env.staging?
3 - If you cannot write to the filesystem let letter_opener know in your config/environments/staging.rb
config.action_mailer.delivery_method = :letter_opener
LetterOpener.cannot_write_to_file_system!
Now we can see it all in action.
First, we request an invite.

Then, we click the link “view the Emails that users would have received” link at the bottom and see an “inbox” of everything the app sent.

Fincally clicking one message lets us preview it just as we did in devellopment

We are able to run on heroku without writing to the file system by using the FakeFS gem which simulates the filesystem in memory. FakeFS is designed to be used for testing and one caveat to be aware of is that your old emails will disappear if heroku recycles your dyno due to inactivity.
I hope you think letter_opener is useful and give it a try the next time you need to send email. Remember here’s a live demo at http://awesome-site-staging.heroku.com/ of the site we’ve been talking about here.
My mom was in town last week, so my sister-in-law Miriam and I decided that she needed to experience dinner at Momofuku Noodle Bar. Turns out, this was an excellent call.
The great thing about the Noodle Bar is that they feature a wide array of seasonal, rotating dishes alongside their greatest hits (pork and mushroom buns, pork ramen, spicy cold noodles with sausage). This time of year, that means both Brussels sprouts and tomatoes. Glorious, right?
We started with the tomato and avocado salad, which ended up having cucumbers, too. I was pretty darn excited. The salad was creamy and fresh and just a wonderful bowl full of early autumn.Next up, shrimp buns. I was a bit nervous about these, with, it turns out, no reason to be. They were amazing. The shrimp were perfect specimens - impossibly plump and sweet - pressed gently into a patty, bound with something delicious and unidentifiable. The patties were made on the griddle, I think, and arrived, piping hot, tucked into their yeasty buns and topped with a spicy mayonnaise and some iceberg lettuce. Slam dunk.
The Brussels sprouts with sausage were delightfully cabbagey - just a bit stinky and beautifully set off by the sausage. Should have been served with a spoon, though, the better to sip up the sprout-y broth. Apples brought a little sweetness to the party, and some puffed grain (they reminded me of Corn Pops, but savory) added crunch.
And, of course, there were noodles. Spicy cold noodles with spinach, sausage and candied cashews. You need the cashews to deal with the spiciness, trust. And chicken ramen, which comes in the very richest chicken broth I have ever tasted in my life. Ever.
Thanks for dinner, Mom - and you're welcome.
![]() |
| @Tenderlove and the rest of the Rails core team deserve some love for speeding up your app! |
We’ve heard a lot about many of the great new features in Rails 3.1: the asset pipeline, Coffee Script, HTTP streaming and on and on. But if you’re still using ActiveRecord with a traditional SQL database, like me, then you’re probably using one of Rails 3.1’s most powerful new features without even realizing it: Prepared Statements.
Database servers such as Postgres and Oracle for years have allowed client applications to preprocess and cache specific SQL statement patterns ahead of time, later allowing the query results to be returned even faster…
Rails 3.2 will come with X-Request-Id tracking and TaggedLogging support!! Recently DHH added this feature here! This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs. If you have application on SAS model. Where you have logs filled with mixed request for all your customers. [...]
I have been working on Scala in my spare time for the past ~3 months now and I absolutely love it! It is extremely powerful, the syntax is sleek and it has an API for almost every basic operation! My choice of IDE so far has been Eclipse which I am a big fan of while [...]![]()
An experience map is a holistic view of all of the touchpoints or interactions people have with a brand. It enables you to determine a number of key factors: Frequency and duration of each touchpoint Levels of satisfaction with each touchpoint Points … Continue reading
The majority of the products and services we use have no lasting impact in our lives, they are a means to an end. We only think about and talk about those that either don’t meet are exceed our expectations. I noticed a … Continue reading
You probably know you can chain ActiveRecord scopes together and it combines it all together into one sql statement, but did you know that you can also use scopes from associated models in your chain?
Let me show you with an example. Let’s say we have a discussion site where users can post comments with two simple models:
class User < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
end
We could display a list of all users with User.all or even display them alphabetically with User.order(:name) (yes I’d create a scope if I were doing this for real).
What if I wanted to display the users sorted so that the ones with the most recent comment was first?
User.includes(:comments).merge(Comment.order('comments.created_at desc'))
There’s a lot going on there, let’s break it down.
User.includes(:comments) - tells active record to query both the users and comments tablesComment.order('comments.created_at desc') - sorts the results by the date of the comment (we need to specify the table and column name since created_at is also a column on the users table)merge(Comment.XXX) - lets us use a scope from the Comment model even though we’re dealing with UsersWhen ActiveRecord and ActiveRelation take all this and convert it into a sql statement it will join the users and comments tables and order by the comments.created_at column. Here’s the sql I actually get in irb (boy am I glad I didn’t have to type that sql myself!).
> User.includes(:comments).merge(Comment.order('comments.created_at desc'))
SQL (0.4ms) SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, "users"."created_at" AS t0_r2,
"users"."updated_at" AS t0_r3, "comments"."id" AS t1_r0, "comments"."user_id" AS t1_r1,
"comments"."body" AS t1_r2, "comments"."created_at" AS t1_r3, "comments"."updated_at" AS t1_r4
FROM "users"
LEFT OUTER JOIN "comments" ON "comments"."user_id" = "users"."id"
ORDER BY comments.created_at desc
It works to type all that but in a real application you’d add scopes to make it easier to work with. Let’s do that!
class User < ActiveRecord::Base
has_many :comments
scope :by_most_recent_comment, includes(:comments).merge(Comment.most_recent_first)
scope :with_recent_comments, includes(:comments).merge(Comment.recently(1.month.ago))
end
class Comment < ActiveRecord::Base
belongs_to :user
scope :most_recent_first, order('comments.created_at desc')
scope :recently, lambda { |date| where('comments.created_at >= ?', date) }
end
Now we can write some nice simple scopes like
User.by_most_recent_comment to get all users sorted so the ones with recent comments are at the topUser.with_recent_comments to get all users who have commented in the past monthUser.with_recent_comments.by_most_recent_comment to get users who have commented in the past month sorted by the date of their most recent comment.Happy scoping!
You probably know you can chain ActiveRecord scopes together and it combines it all together into one sql statement, but did you know that you can also use scopes from associated models in your chain?
Let me show you with an example. Let’s say we have a discussion site where users can post comments with two simple models:
class User < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
end
We could display a list of all users with User.all or even display them alphabetically with User.order(:name) (yes I’d create a scope if I were doing this for real).
What if I wanted to display the users sorted so that the ones with the most recent comment was first?
User.includes(:comments).merge(Comment.order('comments.created_at desc'))
There’s a lot going on there, let’s break it down.
User.includes(:comments) - tells active record to query both the users and comments tablesComment.order('comments.created_at desc') - sorts the results by the date of the comment (we need to specify the table and column name since created_at is also a column on the users table)merge(Comment.XXX) - lets us use a scope from the Comment model even though we’re dealing with UsersWhen ActiveRecord and ActiveRelation take all this and convert it into a sql statement it will join the users and comments tables and order by the comments.created_at column. Here’s the sql I actually get in irb (boy am I glad I didn’t have to type that sql myself!).
> User.includes(:comments).merge(Comment.order('comments.created_at desc'))
SQL (0.4ms) SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, "users"."created_at" AS t0_r2,
"users"."updated_at" AS t0_r3, "comments"."id" AS t1_r0, "comments"."user_id" AS t1_r1,
"comments"."body" AS t1_r2, "comments"."created_at" AS t1_r3, "comments"."updated_at" AS t1_r4
FROM "users"
LEFT OUTER JOIN "comments" ON "comments"."user_id" = "users"."id"
ORDER BY comments.created_at desc
It works to type all that but in a real application you’d add scopes to make it easier to work with. Let’s do that!
class User < ActiveRecord::Base
has_many :comments
scope :by_most_recent_comment, includes(:comments).merge(Comment.most_recent_first)
scope :with_recent_comments, includes(:comments).merge(Comment.recently(1.month.ago))
end
class Comment < ActiveRecord::Base
belongs_to :user
scope :most_recent_first, order('comments.created_at desc')
scope :recently, lambda { |date| where('comments.created_at >= ?', date) }
end
Now we can write some nice simple scopes like
User.by_most_recent_comment to get all users sorted so the ones with recent comments are at the topUser.with_recent_comments to get all users who have commented in the past monthUser.with_recent_comments.by_most_recent_comment to get users who have commented in the past month sorted by the date of their most recent comment.Happy scoping!
One of my favorite talks from TED by Simon Sinek.
Simple, effective and insightful.
![]() |
| Bundler is about to get a lot faster... |
If you’ve worked on a Rails 3 application during the past year or so you’ve probably noticed that running bundle install or bundle update can often take a long, long time to finish. The terminal seems to hang for 30 seconds or more after displaying “Fetching source index for http://rubygems.org/.” Well I have some good news for you: the smart people behind Bundler and RubyGems.org have come up with a solution, and the new version of Bundler about to be released is a lot faster! Today I’m going to take a look at exactly why Bundler 1.1 is so much faster – at what exactly the RubyGems/Bundler teams did to speed it up…
Its Tech tuesday at Pinkbike and they have a very good writeup on finding and fixing creaks in your bicycle
Definitely a must read.
Tools required
Procedure
Common culprits – Seat posts, Stems, Loose quick releases, Bottom Brackets.
Other good reads on how to take care of a noisy bicycle
This is the collection of some of my poems written in my mother tongue - Marathi language :-
http://dhundamanasi.wordpress.com/about/
http://dhundamanasi.wordpress.com/
Enjoy ... :-)
A quickie post about the next awesome bicycle race in Bangalore – Race to Nandi Top!
Race route: Siva’s road – Nandi arch
Distance: ~50 km
Time: 0730 hrs
This is one of the most awaited races of the season and it would be awesome to have a lot of riders racing this.
Please do help us by talking about the race to anyone and everyone who might consider getting on self powered wheels.
If you need transport to the race start or post race please connect with Dinesh (dineshrvernekar at gmail.com).
Please also help in adding some positiveness to the Vit M kitty that helps sustain the races.
As always, we need more volunteers, so please sign up in case you are not racing.
Generators got a complete makeover with Rails 3 making them much easier to write but they’ve been very hard to test if you’re using RSpec. That’s changed now with the Ammeter Gem which lets you write RSpec specs for your generators.
Unless you’ve writing a gem you probably haven’t created a generator, but I bet you’re using one someone else created. If you’ve ever typed
There are a number of resources for writing generators using thor including the generators guide or railscast #218 and I’m not going to go into that here. If you’re using TestUnit, like the rails core team, you can use Generators::TestCase which is part of Rails - Devise has some good examples. For those of us using RSpec we can now use Ammeter.
First you need to tell your gem to use ammeter by 1) adding it to our bundle and 2) making it accessible to our specs.
# <YOUR_GEM_NAME>.gemspec
s.add_development_dependency 'ammeter'
# spec_helper.rb
require 'ammeter/init'
Then we specify the behavior. We’ll look at an example using Mongoid’s config generator and its spec config_generator_spec. The generator’s usage is rails generate mongoid:config [DATABASE_NAME] [options].
# spec/generators/mongoid/config/config_generator_spec.rb
require 'spec_helper'
# Generators are not automatically loaded by Rails
require 'rails/generators/mongoid/config/config_generator'
class Rails::Application; end
class MyApp::Application < Rails::Application; end
describe Mongoid::Generators::ConfigGenerator do
# Tell the generator where to put its output (what it thinks of as Rails.root)
destination File.expand_path("../../../../../../tmp", __FILE__)
before { prepare_destination }
describe 'no arguments' do
before { run_generator }
describe 'config/mongoid.yml' do
subject { file('config/mongoid.yml') }
it { should exist }
it { should contain "database: my_app_development" }
end
end
describe 'specifying database name' do
before { run_generator %w(my_database) }
describe 'config/mongoid.yml' do
subject { file('config/mongoid.yml') }
it { should exist }
it { should contain "database: my_database_development" }
end
end
end
There’s some boilerplate setup you’ll need at the top of your spec:
Now for the behavior:
When you’re generating migrations it is somewhat tricky because migration file names contain a timestamp. We need another example and will use acts_as_taggable-on’s migration generator We could write a spec for this as
# spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb
require 'spec_helper'
# Generators are not automatically loaded by Rails
require 'generators/acts_as_taggable_on/migration/migration_generator'
describe ActsAsTaggableOn::MigrationGenerator do
# Tell the generator where to put its output (what it thinks of as Rails.root)
destination File.expand_path("../../../../../tmp", __FILE__)
before do
prepare_destination
Rails::Generators.options[:rails][:orm] = :active_record
end
describe 'no arguments' do
before { run_generator }
describe 'db/migrate/acts_as_taggable_on_migration.rb' do
subject { file('db/migrate/acts_as_taggable_on_migration.rb') }
it { should be_a_migration }
end
end
end
You can see much of the same setup and then the new matcher
An Ammeter is a measuring instrument used to measure the electric current in a circuit. Generators produce electricity and your specs measure your generators … cute huh :)
Try Ammeter for your generators, I hope you find it useful. If it doesn’t meet your needs fork away - Ammeter is on github. I welcome any feedback, issues or pull requests.
Generators got a complete makeover with Rails 3 making them much easier to write but they’ve been very hard to test if you’re using RSpec. That’s changed now with the Ammeter Gem which lets you write RSpec specs for your generators.
Unless you’ve writing a gem you probably haven’t created a generator, but I bet you’re using one someone else created. If you’ve ever typed
There are a number of resources for writing generators using thor including the generators guide or railscast #218 and I’m not going to go into that here. If you’re using TestUnit, like the rails core team, you can use Generators::TestCase which is part of Rails - Devise has some good examples. For those of us using RSpec we can now use Ammeter.
First you need to tell your gem to use ammeter by 1) adding it to our bundle and 2) making it accessible to our specs.
# <YOUR_GEM_NAME>.gemspec
s.add_development_dependency 'ammeter'
# spec_helper.rb
require 'ammeter/init'
Then we specify the behavior. We’ll look at an example using Mongoid’s config generator and its spec config_generator_spec. The generator’s usage is rails generate mongoid:config [DATABASE_NAME] [options].
# spec/generators/mongoid/config/config_generator_spec.rb
require 'spec_helper'
# Generators are not automatically loaded by Rails
require 'rails/generators/mongoid/config/config_generator'
class Rails::Application; end
class MyApp::Application < Rails::Application; end
describe Mongoid::Generators::ConfigGenerator do
# Tell the generator where to put its output (what it thinks of as Rails.root)
destination File.expand_path("../../../../../../tmp", __FILE__)
before { prepare_destination }
describe 'no arguments' do
before { run_generator }
describe 'config/mongoid.yml' do
subject { file('config/mongoid.yml') }
it { should exist }
it { should contain "database: my_app_development" }
end
end
describe 'specifying database name' do
before { run_generator %w(my_database) }
describe 'config/mongoid.yml' do
subject { file('config/mongoid.yml') }
it { should exist }
it { should contain "database: my_database_development" }
end
end
end
There’s some boilerplate setup you’ll need at the top of your spec:
Now for the behavior:
When you’re generating migrations it is somewhat tricky because migration file names contain a timestamp. We need another example and will use acts_as_taggable-on’s migration generator We could write a spec for this as
# spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb
require 'spec_helper'
# Generators are not automatically loaded by Rails
require 'generators/acts_as_taggable_on/migration/migration_generator'
describe ActsAsTaggableOn::MigrationGenerator do
# Tell the generator where to put its output (what it thinks of as Rails.root)
destination File.expand_path("../../../../../tmp", __FILE__)
before do
prepare_destination
Rails::Generators.options[:rails][:orm] = :active_record
end
describe 'no arguments' do
before { run_generator }
describe 'db/migrate/acts_as_taggable_on_migration.rb' do
subject { file('db/migrate/acts_as_taggable_on_migration.rb') }
it { should be_a_migration }
end
end
end
You can see much of the same setup and then the new matcher
An Ammeter is a measuring instrument used to measure the electric current in a circuit. Generators produce electricity and your specs measure your generators … cute huh :)
Try Ammeter for your generators, I hope you find it useful. If it doesn’t meet your needs fork away - Ammeter is on github. I welcome any feedback, issues or pull requests.
Hi Folks, If you are doing any application in which you required JRuby as a platform. You can use Rails3.1 with that. activerecord-jdbc-adapter 1.2.0 is ok with that! All the steps are same as for the normal Rails Application You can find more details here http://blog.jruby.org/2011/09/ar-jdbc-1-2-0-released/ Cheers, Arun
Hello, my dear, darling, wonderful readers! I know there's been quite a bit of radio silence around these parts of late, and I heartily apologize. It's been a busy summer/early autumn in Queenie land, and I'm just now back from a ten-day trip to one of my favorite places - Austin, Texas.
There's lots to report on (barbecue, a homemade Thai feast), but for now, just enjoy these adorable pictures of dogs.
Back soon with lots more, I promise.
![]() |
| My step_definitions folder looks like this... |
This week I decided to look through my features/step_definitions folder after reading Aslak Hellesøy’s post from Wednesday about removing web_steps.rb. I was worried that I might need to write many more custom steps since web_steps.rb will disappear the next time I upgrade Cucumber.
What I found was a mess! First of all, there were a lot of step files and no naming convention that might help me find a particular step, and each step file was a loose collection of step definitions that weren’t organized or DRY…
It is not another project, this one is going to be game changing. It will revolutionize how people think about the subject, change the way they work, shake up the industry and position us as global leaders in the space. People … Continue reading
Its a Monday! Let’s indulge in some awesome Bicycling.
We would also be watching these on our bigass wide screen @ BumsOnTheSaddle. Whoohooo!
Everyone is welcome to join. More the merrier :)
Stuff we are watching (mostly, depending on time and interest)
I recently had to upgrade an old app and it went pretty smoothly so I thought I’d share how I did it.
I thought about two approaches to this upgrade
I downloaded the old code and immediately remembered the pain of getting an app up and running without bundler. This convinced me that #1 would be harder than it needed to be so I decided to go with approach #2. It worked out pretty well so I’m going to share exactly what I did.
$ rails new waywework
create
create README
create Rakefile
# and a lot more...
run bundle install
Fetching source index for http://rubygems.org/
Using rake (0.9.2)
# and a lot more...
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
Because the old app comes from the days before bundler I had to look in config/environment.rb for lines like config.gem 'atom' and guess what else I needed (I knew I was using rspec).
#Gemfile
gem 'atom'
group :development, :test do
gem "rspec-rails"
gem "factory_girl_rails"
gem "haml-rails"
gem 'faker'
end
Now we can make sure our empty app works (even though it does nothing)
$ cd waywework
$ rails g rspec:install
create .rspec
create spec
create spec/spec_helper.rb
$ rake db:migrate
$ rake
No examples matching ./spec/**/*_spec.rb could be found
$ cp -r ~/old_waywework/app/controllers/* app/controllers
$ cp -r ~/old_waywework/app/models/* app/models
$ cp -r ~/old_waywework/app/helpers/* app/helpers
$ cp -r ~/old_waywework/app/views/* app/views
$ cp -r ~/old_waywework/db/migrate db
$ mv spec/spec_helper.rb new_spec_helper.rb
$ cp -r ~/old_waywework/spec/* spec
$ mv new_spec_helper.rb spec/spec_helper.rb
Now when we try to run the specs it tells us we have pending migrations so we run them
$ rake
You have 5 pending migrations:
20081022162743 CreateFeeds
20081022162832 CreatePosts
20081031025747 IndexPublishedInPosts
20081031143453 IndexFeedAuthor
20081103143931 PublishedAsDatetime
$ rake db:migrate
== CreateFeeds: migrating ====================================================
-- create_table(:feeds)
-> 0.0025s
== CreateFeeds: migrated (0.0026s) ===========================================
== CreatePosts: migrating ====================================================
-- create_table(:posts)
-> 0.0021s
== CreatePosts: migrated (0.0023s) ===========================================
== IndexPublishedInPosts: migrating ==========================================
-- add_index(:posts, [:published, :feed_id])
-> 0.0015s
== IndexPublishedInPosts: migrated (0.0017s) =================================
== IndexFeedAuthor: migrating ================================================
-- add_index(:feeds, :author)
-> 0.0007s
== IndexFeedAuthor: migrated (0.0008s) =======================================
== PublishedAsDatetime: migrating ============================================
-- change_column(:posts, :published, :datetime)
-> 0.0086s
-- add_column(:posts, :updated, :datetime)
-> 0.0006s
== PublishedAsDatetime: migrated (0.0094s) ===================================
$ rake
...LOTS OF ERRORS...
activerecord-3.1.0/lib/active_record/base.rb:1083:
in `method_missing': undefined method `named_scope' for #<Class:0x103875b28> (NoMethodError)
Now we’re getting some errors and are ready to get to work.
Of course it doesn’t just work and we need to make a number of changes. The guides include an upgrade process section and the rails_upgrade plugin can help identify problems. Here are the ones I found.
named_scope to scopeWith Rails 3 the syntax for scopes changed from named_scope to scope. So we search-and-replace in our models. Once we do this the specs run, but many are failing. A lot are failing because the routes.rb syntax changed in Rails 3.
The constant RAILS_ROOT no longer exists so we need to search-and-replace that with Rails.root.
# OLD config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.posts_by_author 'author/:id', :controller=>'posts', :action=>'by_author'
map.posts_by_month 'month/:year/:month', :controller=>'posts', :action=>'by_month'
map.atom_feed '/atom', :controller => "posts", :action=>'index', :format=>'atom'
map.resources :feeds
map.root :controller => "posts"
end
We change it to:
# NEW config/routes.rb
WayWeWork::Application.routes.draw do
match 'author/:id' =>'posts#by_author', :as => :posts_by_author
match 'month/:year/:month' =>'posts#by_month', :as => :posts_by_month
match '/atom' => 'posts#index', :as => :atom_feed, :format => :atom
resources :feeds
root :to => 'posts#index'
end
We have a bunch of routing specs that are failing because RSpec changed the syntax around routing specs.
# OLD spec/controllers/feeds_routing_spec.rb
it "should map #index" do
route_for(:controller => "feeds", :action => "index").should == "/feeds"
end
it "should generate params for #index" do
params_from(:get, "/feeds").should == {:controller => "feeds", :action => "index"}
end
The routing spec must be in folder called routing
# NEW spec/feeds_routing_spec.rb
it "should generate params for #index" do
get("/feeds").should route_to('feeds#index')
end
stub!Another syntax change in RSpec from using stubs to stub!
# OLD
it 'should ...' do
#...
feed.stubs(:puts)
feed.get_latest
end
We get an error undefined method 'stubs' for \#<Feed:0x105d572e8>
# NEW
it 'should ...' do
#...
feed.stub!(:puts)
feed.get_latest
end
Hmm I’m surprised I had written view specs. Nowadays I would write cucumber features and never write view specs. That being said there were a few things I needed to change to get the view specs passing, all related to RSpec syntax changes.
I was passing @ variables to the view with assigns[:feed] = @feed = stub_model(Feed) and today you need to do that with assign(:feed, @feed = stub_model(Feed). Also when you call render "/feeds/edit.html.erb" it used to work but now tries to render a partial. Plain old render will work as long as you’ve put the filename in your describe like describe "/feeds/edit.html.erb" do
The old app was deployed to a VPS using Capistrano. Today I prefer to use Heroku and there were a few changes I had to make to get it working there.
pg to my Gemfile to support Postgresqlconfig.assets.compile = true in my production.rb ** Added therubyracer to my GemfileCapfileNow I was able to deploy to heroku and the new app is up and running. All this done in less than a day!
I recently had to upgrade an old app and it went pretty smoothly so I thought I’d share how I did it.
I thought about two approaches to this upgrade
I downloaded the old code and immediately remembered the pain of getting an app up and running without bundler. This convinced me that #1 would be harder than it needed to be so I decided to go with approach #2. It worked out pretty well so I’m going to share exactly what I did.
$ rails new waywework
create
create README
create Rakefile
# and a lot more...
run bundle install
Fetching source index for http://rubygems.org/
Using rake (0.9.2)
# and a lot more...
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
Because the old app comes from the days before bundler I had to look in config/environment.rb for lines like config.gem 'atom' and guess what else I needed (I knew I was using rspec).
#Gemfile
gem 'atom'
group :development, :test do
gem "rspec-rails"
gem "factory_girl_rails"
gem "haml-rails"
gem 'faker'
end
Now we can make sure our empty app works (even though it does nothing)
$ cd waywework
$ rails g rspec:install
create .rspec
create spec
create spec/spec_helper.rb
$ rake db:migrate
$ rake
No examples matching ./spec/**/*_spec.rb could be found
$ cp -r ~/old_waywework/app/controllers/* app/controllers
$ cp -r ~/old_waywework/app/models/* app/models
$ cp -r ~/old_waywework/app/helpers/* app/helpers
$ cp -r ~/old_waywework/app/views/* app/views
$ cp -r ~/old_waywework/db/migrate db
$ mv spec/spec_helper.rb new_spec_helper.rb
$ cp -r ~/old_waywework/spec/* spec
$ mv new_spec_helper.rb spec/spec_helper.rb
Now when we try to run the specs it tells us we have pending migrations so we run them
$ rake
You have 5 pending migrations:
20081022162743 CreateFeeds
20081022162832 CreatePosts
20081031025747 IndexPublishedInPosts
20081031143453 IndexFeedAuthor
20081103143931 PublishedAsDatetime
$ rake db:migrate
== CreateFeeds: migrating ====================================================
-- create_table(:feeds)
-> 0.0025s
== CreateFeeds: migrated (0.0026s) ===========================================
== CreatePosts: migrating ====================================================
-- create_table(:posts)
-> 0.0021s
== CreatePosts: migrated (0.0023s) ===========================================
== IndexPublishedInPosts: migrating ==========================================
-- add_index(:posts, [:published, :feed_id])
-> 0.0015s
== IndexPublishedInPosts: migrated (0.0017s) =================================
== IndexFeedAuthor: migrating ================================================
-- add_index(:feeds, :author)
-> 0.0007s
== IndexFeedAuthor: migrated (0.0008s) =======================================
== PublishedAsDatetime: migrating ============================================
-- change_column(:posts, :published, :datetime)
-> 0.0086s
-- add_column(:posts, :updated, :datetime)
-> 0.0006s
== PublishedAsDatetime: migrated (0.0094s) ===================================
$ rake
...LOTS OF ERRORS...
activerecord-3.1.0/lib/active_record/base.rb:1083:
in `method_missing': undefined method `named_scope' for #<Class:0x103875b28> (NoMethodError)
Now we’re getting some errors and are ready to get to work.
Of course it doesn’t just work and we need to make a number of changes. The guides include an upgrade process section and the rails_upgrade plugin can help identify problems. Here are the ones I found.
named_scope to scopeWith Rails 3 the syntax for scopes changed from named_scope to scope. So we search-and-replace in our models. Once we do this the specs run, but many are failing. A lot are failing because the routes.rb syntax changed in Rails 3.
The constant RAILS_ROOT no longer exists so we need to search-and-replace that with Rails.root.
# OLD config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.posts_by_author 'author/:id', :controller=>'posts', :action=>'by_author'
map.posts_by_month 'month/:year/:month', :controller=>'posts', :action=>'by_month'
map.atom_feed '/atom', :controller => "posts", :action=>'index', :format=>'atom'
map.resources :feeds
map.root :controller => "posts"
end
We change it to:
# NEW config/routes.rb
WayWeWork::Application.routes.draw do
match 'author/:id' =>'posts#by_author', :as => :posts_by_author
match 'month/:year/:month' =>'posts#by_month', :as => :posts_by_month
match '/atom' => 'posts#index', :as => :atom_feed, :format => :atom
resources :feeds
root :to => 'posts#index'
end
We have a bunch of routing specs that are failing because RSpec changed the syntax around routing specs.
# OLD spec/controllers/feeds_routing_spec.rb
it "should map #index" do
route_for(:controller => "feeds", :action => "index").should == "/feeds"
end
it "should generate params for #index" do
params_from(:get, "/feeds").should == {:controller => "feeds", :action => "index"}
end
The routing spec must be in folder called routing
# NEW spec/feeds_routing_spec.rb
it "should generate params for #index" do
get("/feeds").should route_to('feeds#index')
end
stub!Another syntax change in RSpec from using stubs to stub!
# OLD
it 'should ...' do
#...
feed.stubs(:puts)
feed.get_latest
end
We get an error undefined method 'stubs' for \#<Feed:0x105d572e8>
# NEW
it 'should ...' do
#...
feed.stub!(:puts)
feed.get_latest
end
Hmm I’m surprised I had written view specs. Nowadays I would write cucumber features and never write view specs. That being said there were a few things I needed to change to get the view specs passing, all related to RSpec syntax changes.
I was passing @ variables to the view with assigns[:feed] = @feed = stub_model(Feed) and today you need to do that with assign(:feed, @feed = stub_model(Feed). Also when you call render "/feeds/edit.html.erb" it used to work but now tries to render a partial. Plain old render will work as long as you’ve put the filename in your describe like describe "/feeds/edit.html.erb" do
The old app was deployed to a VPS using Capistrano. Today I prefer to use Heroku and there were a few changes I had to make to get it working there.
pg to my Gemfile to support Postgresqlconfig.assets.compile = true in my production.rb ** Added therubyracer to my GemfileCapfileNow I was able to deploy to heroku and the new app is up and running. All this done in less than a day!
![]() |
| Libxml2 powers your BDD/integration tests that use the default Capybara driver |
If you’re a Rails developer using Behavior Driven Development, then you’re probably using either Cucumber features or RSpec integration tests with the Capybara gem to simulate what a user would do with a real browser. You probably know that by default Capybara uses a driver based on Rack to connect to your Rails app and make simulated HTTP requests, all within the same process using only Ruby…