27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

344 CHAPTER 12 Sending email<br />

When you run this spec using bin/rspec spec/mailers/receiver_spec.rb, you’ll<br />

be told this:<br />

Failure/Error: lambda { Receiver.parse(mail) }.should(<br />

undefined method `parse' for Receiver:Class<br />

To make this spec parse, you need to define this method. This method should take a<br />

Mail::Message object, read out everything from the body of that object above the line<br />

“ADD YOUR REPLY ABOVE THIS LINE”, and create a comment from it. You can begin<br />

to define this method in app/mailers/receiver.rb like this:<br />

def self.parse(email)<br />

reply_separator = /(.*?)\s?== ADD YOUR REPLY ABOVE THIS LINE ==/m<br />

comment_text = reply_separator.match(email.body.to_s)<br />

Here you match the body of the email with the expected reply separator, getting back<br />

either a MatchData object (indicating the email is a valid reply to a comment) or nil.<br />

If you get back a valid reply then you do this:<br />

if comment_text<br />

to, project_id, ticket_id =<br />

email.to.first.split("@")[0].split("+")<br />

Here you take the list of to addresses for the email, get the first of them, and then<br />

split it on the @ symbol. This separates the username and the domain name in your<br />

email. The username contains the project id and ticket id, which you get by calling<br />

split again, this time separating the individual elements by the + symbol.<br />

Next, you need to find the relative project, ticket, and user for this email, which<br />

you can do using these lines inside the if that you just opened:<br />

project = Project.find(project_id)<br />

ticket = project.tickets.find(ticket_id)<br />

user = User.find_by_email(email.from[0])<br />

Finally, you need to create the comment from the email body (stripping all extra<br />

spaces from it) and close the if, which is done with the following lines:<br />

ticket.comments.create(:text => comment_text[1].strip,<br />

:user => user)<br />

end<br />

end<br />

The [1] here will get the first match for the comment_text, which will be the new comment’s<br />

text, throwing strip on the end in case there are a couple of extra spaces /<br />

lines between the comment text and the separator. That’s the final bit of code you<br />

need in the app/mailers/receiver.rb file. When you run this spec again with bundle<br />

exec rspec spec/mailers/receiver_spec.rb, it will still fail:<br />

Failure/Error: lambda { Receiver.parse(mail) }.should(<br />

count should have been changed by 1, but was changed by 0

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

Saved successfully!

Ooh no, something went wrong!