Big Paybackable upgrade - live!
Well, it took us about a week longer than we thought, but we just released a major upgrade to Paybackable. There are 2 key elements to the release:
- The ability to create company accounts and add employees
- We added paid account plans
We also rolled out a new look and feel that was created by real designers, as opposed to Kevin hacking around.
So we’ll be giving DHH’s “advice” a whirl and trying to actually charge money for a useful web service.
If you know any small companies who want to simplify their online expense reporting, please send them our way
Bootstrap is coming…

Self employment is about to get easier…
We have officially moved into private alpha on Bootstrap, our first major homegrown application. We aren’t saying much about it at this point while select users are banging away on it. But we can say this - it will definitely increase the time an entrepreneur can spend growing a business, rather than dealing with the hassles of running it. It’s entirely web-based and will work on all the major browsers…:-)
If you would like to learn more about Bootstrap, go to our home page at www.gobootstrap.com and submit your email. We’ll keep you posted as we open access to more folks and unveil specific features.
Quicken Mobile launches at MacWorld
QuickenMobile , a cool little app we built for Intuit, was launched at MacWorld this week. It sends you text messages with balances and recent transactions for your bank and credit card accounts. We built it in JRuby on Rails to interface with Intuit’s java-based aggregation web service and deploy within their java stack. Here’s the beta sign up screen.

In addition to the transaction aggregation and sms capabilities, one of Intuit’s own, Zach “Money” Moneypenny built an iPhone interface for the application. He was working the show when we stopped by - here he was bringing it up on his iPhone.

Have to say, it was cool seeing something we built being demoed at MacWorld. We even heard that a senior member of the Google mobile team found it to be pretty cool. It was also very nice to see the other apps the Quicken team were showing off. In addition to QuickenOnline, which also just launched, they were demonsrating the coming version of Quicken for the Mac. What I found particularly interesting is that the entire program is being re-written from the ground up using Cocoa. From what I saw, it looks great. They’re about to go into Beta and both Ben and I signed up. Here’s a pic of what I like to call Cocoa Quicken…

We didn’t spend a ton of time at the expo, but while we were there it was pretty crowded. The logistics of getting in were terrible - our passes didn’t have promo codes, which the registration software required, there were tons of different lines with the exact same signs above them, and the badging process was a hilarious cluster. I’d be curious to know the results of a process excellence evaluation of IDG’s logistical approach. But I shouldn’t complain - I wouldn’t want to solve that issue for a living.
We did stop by the MacBook Air, though it took some effort to actually get your hands on one. It was kind of funny that everyone one wanted to pick them up and play with them, but you had to keep them over the counter. Made for an interesting dynamic (see pic below:)

Our final stop before heading out was to chat with the folks at NeatReceipts, who were showing off their receipt scanning solution for the Mac. We’re talking to them about integration with Paybackable and our “kinda secret” forthcoming app. Stay tuned for more on that.
Mileage expense tracking, anyone?
We released an update to Paybackable.com this morning that adds mileage expense tracking. It uses up-to-date IRS rates (now 50.5 cents per mile for 2008) to calculate how much you can get reimbursed for those business miles. Just enter the date of travel, a description (purpose of trip, destination, who you saw, etc.) and the miles driven and Paybackable will calculate the correct amount.
One other interesting note about this feature: it actually solves a gap in QuickBooks. Their vehicle mileage tracking feature doesn’t support reimbursing employees for their miles. To quote their support site: “You cannot use vehicle mileage tracking to reimburse your employees for mileage.” Their suggested solution is to create a bill payable to the employee (or vendor) with line items for the trips. This is precisely what Paybackable does, which is nice.
Check it out at www.paybackable.com
Bug in JRuby BigDecimal.to_s when amount is in cents
We found an interesting bug yesterday while working on one of our JRuby projects. In our application we are downloading transactions from various banks. I noticed an interesting bug while testing against my bank account where transactions with only cents and no whole amount were downloaded incorrectly. A transaction for $0.45 would, incorrectly be downloaded as $4.50. We determined that the issue stemmed from a JRuby bug in BigDecimal. The following test cases showcase the bug.
BigDecimal.new("0.10").to_s("F") => "1.0" BigDecimal.new("0.01").to_s("F") => "1.0"
I have created a patch for JRuby 1.0.2 which fixes the issue. I have submitted to the JRuby project and Headius told me it should make it into JRuby 1.0.3 and also the trunk. If you can’t wait for 1.0.3, which is due in the next couple of weeks, you can download the patch I submitted. If you are too lazy to apply the patch your self, let me know and I’ll send you the JRuby jar file with the applied patch that I created for our project.
www.paybackable.com
Well, we got frustrated enough with handling our own out-of-pocket expenses that we wrote a small app to help create online expense reports. It’s live at http://www.paybackable.com. It lets you track expenses and submit expense reports as IIF files for import into QuickBooks. It will also pull the expense categories from a QuickBooks chart of accounts IIF file so everything matches up. There are some nifty elements, like auto-complete of payee names with memorized categorization, plus keyboard shortcuts for quickly changing the date.
While it’s been very helpful for us (took the whole process from 20-30 minutes per expense report down to less than 5), we were wondering if anyone else might find it useful. Feel free to give it a try and let us know what you think. You can email me (Kevin) at esomnie dot com
HTTP Basic Authentication using restful_authentication with Rails 1.2
I ran into a small issue this morning with the restful_authentication plugin. We are developing an application where we need to provide a JSON data feed. The feed is protected using HTTP Basic Authentication. There is currently a bug in the plugin which makes Basic Authentication fail. When using the following curl command, I kept receiving a 406 http code from the server.
curl -X GET --basic -u bcurren:test http://localhost:3000/accounts.js
The reason for the 406 error was two fold: 1. there was a bug in restful_authentication which rejects all username and password combinations, even if they are valid 2. restful_authentication does not respond to js requests, so a 406 error is returned, meaning the request type is not valid.
To fix the bug in restful_authentication, I changed the following:
def login_required self.current_user ||= User.authenticate(username, passwd) || :false if username && passwd logged_in? && authorized? ? true : access_denied end
to the following
def login_required if self.current_user == :false && username && passwd self.current_user = User.authenticate(username, passwd) || :false end logged_in? && authorized? ? true : access_denied end
The bug is a result of :false being returned from current_user rather than false or nil. Since :false is a symbol it always evaluates to true when used in conditions. The updated code explicitly test if the current_user == :false
After the bug fix above, I was able to successfully retrieve the JSON feed when supplying a valid username and password. However, when submitting and invalid username and password, the application was return a 406 code rather than a 401. This does not result from a bug in restful_authentication but from a lack of support for js requests out of the box. I simply added the following to the access_deniedmethod in authentication_system.rb.
accepts.js do headers["Status"] = "Unauthorized" headers["WWW-Authenticate"] = %(Basic realm="Web Password") render :text => "Could't authenticate you", :status => '401 Unauthorized' end
I hope this post helps anyone who is tackling the similar issue in Rails 1.2. I will post about some of the other trail and tribulations of using the to_json method in Rails 1.2 in the near future.
Thinking outside the box
Early today I was talking with Dean, our new Web Developer, about how I started hacking in Ruby. Like many Ruby hackers these days, I started off using Rails and then became more and more interested in Ruby. When I developed my first small Rails web application it was rather apparent at how much faster I could write clean, testable code. I also immediately began to wonder, how does Rails perform all of its magic?
The natural place to start looking was in the Rails source code. I was immediately impressed at how dynamic Ruby was. After I started to grasp the code base and some of the patterns, I started to fall in love with Ruby. The power of Rails lies in Ruby. I know there are plenty of other beautiful languages out there, but my background was mainly with c, C++, C#, Java, and PHP, so some of the Ruby features were quite new to me. After learning Ruby, I realized that my whole career, I was solving problems in a box. My problem solving and design skills were constrained by the programming language at my disposal. The dynamic power of Ruby opened that box and I now tackle problems in a new light. The more Ruby code I read the more my toolset grows and the more ways I can look at solving a problem.
I keep thinking, what will the next programming language be that changes the way I think this much? Is it something I can even imagine right now? It’s strange how paradigms shape our world and make it so difficult to think outside the box.
Using url_for in Ruby on Rails tests
On a recent Ruby on Rails project, we ran into a situation where we needed to use the ActionController::Base url_for method in our tests. My first attempt was to simply write the test as follows:
def test_next__should_show_step3 @request.env["HTTP_REFERER"] = @controller.url_for( :controller => 'wizard', :action => 'step', :step_number => "1", :id => 1) post :next, :id => 1 assert_not_nil assigns(:virtual_tour) assert_response :redirect assert_redirected_to :action => 'step', :step_number => "3", :id => assigns(:virtual_tour).id end
When I ran the test it resulted in the following error:
test_next__should_show_step3(VirtualTourWizardControllerTest): NoMethodError: You have a nil object when you didn't expect it! The error occured while evaluating nil.rewrite /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:488:in `url_for' ./test/functional/virtual_tour_wizard_controller_test.rb:91:in `set_referer_step' ./test/functional/virtual_tour_wizard_controller_test.rb:64:in `test_next__should_update_virtual_tour'
When we looked at the rails code, we saw that an instance variable @url was not initialized yet in our tests. This was causing the nil error seen above. We found a post that wrote about a work around by initializing this variable by calling get :index or some other action that doesn’t cause a side effect. This seems like a bit of a hack so we dug a little further.
After a little digging in the rails source code, we found the class that does the actual URL rewriting. The class is called ActionController::UrlRewriter which url_for delegates to to do the actual URL rewriting. So we created a little helper method in test_helper.rb to wrap ActionController::UrlRewriter in a nice helper method called url_for. The following is the method we created in test_helper.rb
def url_for(options) url = ActionController::UrlRewriter.new(@request, nil) url.rewrite(options) end
We can know rewrite our test to look like this.
def test_next__should_show_step3 @request.env["HTTP_REFERER"] = url_for( :controller => 'wizard', :action => 'step', :step_number => "1", :id => 1) post :next, :id => 1 assert_not_nil assigns(:virtual_tour) assert_response :redirect assert_redirected_to :action => 'step', :step_number => "3", :id => assigns(:virtual_tour).id end
We ended up doing a little more refactoring after this since we set the referer like this in many of our other tests.
Migrating Typo Feeds to FeedBurner using Mongrel
Daminen Tanner has a nice article on migrating your Typo feeds to FeedBurner. However, his implementation for redirecting the feeds does not work for my setup since I am using Mongrel. I could not seem to find a documented solution so I came up with one myself. The solution I came up with will also work with any deployment since I modified the Typo code to perform the redirects rather than configuring the server to do so.
I wanted to make sure that I did not change any of the Typo feed URLs. I want to keep ownership of these in case sometime in the future I decide not to use FeedBurner. If I directly gave out the FeedBurner URL than it would be extremely difficult to seamlessly migrate to another service in the future.
On another note, I found a blog written by the FeedBurner folks that states:
Notice that we use a temp redirect. If we used permanent instead, readers would forget the old URL and just use the new URL permanently. In our pre-alpha service phase, we donââ¬â¢t yet recommend permanent redirection.
I donââ¬â¢t think that FeedBurner is still in a pre-alpha phase, but once again, I donââ¬â¢t want a reader to forget the old URL. I want readers to continue to using the URL I am in control of so, one day in the future, I can using another service or no service at all. Therefore, I decided to use a temp redirect rather than a permanent redirect.
Enough rambling. Here are the details. The line numbers and code here is based on Typo 4.0.3. In the file app/controllers/xml_controller.rb, line 42, replace the following line:
render :action => "#{@format}_feed"
with
# Want to redirect to FeedBurner unless FeedBurner is the user-agent. if @request.user_agent =~ /FeedBurner/ || @format == 'googlesitemap' render :action => "#{@format}_feed" else redirect_to "http://feeds.feedburner.com/JotThought" end
Donââ¬â¢t forget to replace my FeedBurner URL with your own.
Then, at the top of this file youââ¬â¢ll need to disable caching of the feed. This is necessary because after the feed is cached it will no longer redirect correctly. I am going to look into this more to find a better solution. This will work for me in the meantime.
class XmlController < ContentController caches_action_with_params :feed session :off ...
with
class XmlController < ContentController #caches_action_with_params :feed session :off ...
Thatââ¬â¢s it. All that is left to do is clear the Typo cache and restart Mongrel.
While doing this, I was thinking that I should just create a patch for Typo with a full solution. It would be very simple to add an option in the admin pages that allow anyone to specify their FeedBurner URL. I would then make the code above conditional and grab the FeedBurner URL from the Blog model object. If I have time over the next couple of days, I will create a patch and post the details here.