27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

464 CHAPTER 16 Basic performance enhancements<br />

When a worker reads this row, it will convert this marshalled object back into a real<br />

object and then call the perform method on it. The reason for making another class<br />

and using a Struct over using one such as the Comment is that a Struct object will<br />

always be lighter than a full-on class that inherits from ActiveRecord::Base. If you<br />

enqueued a Comment object instead, the result would be this:<br />

"--- !ruby/<br />

ActiveRecord:Comment \nattributes: \n text: This is a comment\n ticket<br />

_id: 1\n user_id: 2\n created_at: &id001 2011-04-<br />

21 09:35:20.497749 Z\n updated_at: *id001\n state_id: \n previous_sta<br />

te_id: \n id: 1\n"<br />

This contains a lot of useless information that you don’t care about when you’re<br />

enqueueing the job, and so you should not use it. When enqueueing jobs, you should<br />

always try for the lightest possible solution so that the job is queued quickly.<br />

Now when a comment is created, a job will be enqueued to notify the watchers of<br />

the relevant ticket. This job is actually a record in a table called delayed_jobs that the<br />

worker reads from, running each job one at a time and working them off the queue.<br />

When there are no more jobs, it will simply wait.<br />

To make sure that this is working, you’re going to write a test for it. The test should<br />

check that a job is enqueued when a comment is created and that the watchers of the<br />

comment’s ticket are notified by email when the job is run. Primarily, this test will<br />

check the perform method in the Comment model, and so you’ll put it in spec/models/<br />

comment_spec.rb, using the code shown in the following listing.<br />

Listing 16.7 spec/models/comment_spec.rb<br />

require 'spec_helper'<br />

describe Comment do<br />

let(:user) { Factory(:user) }<br />

before do<br />

@ticket = Factory(:ticket)<br />

@ticket.watchers "This is a comment",<br />

:user => ticket.user)<br />

Delayed::Job.count.should eql(1)<br />

Delayed::Worker.new.work_off!<br />

Delayed::Job.count.should eql(0)<br />

email = ActionMailer::Base.deliveries.last<br />

email.to.should eql(user.email)<br />

end<br />

end<br />

At the beginning of the describe Comment block, you set up a user who will be the<br />

one to watch the ticket that you set up in the before block.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!