Slow Runt 3
While unit testing some code that I’ve been working on that uses the excellent runt library, I ran into a bit of code that was quite slow. When calling the include? method of the Runt::DIMonth class with a negative value for the week of the month argument (i.e. DIMonth.new(-1,6).include?(date)) it took over 120 seconds to execute my unit tests.
I replaced the method max_day_of_month (Runt::TExprUtils), as listed below:
def max_day_of_month(date)
result = 1
next_month = nil
if(date.mon==12)
next_month = Date.new(date.year+1,1,1)
else
next_month = Date.new(date.year,date.mon+1,1)
end
date.step(next_month,1){ |d| result=d.day unless d.day < result }
result
end
with the following code:
def max_day_of_month(date)
month = date.month
year = date.year
if month == 2
!year.nil? && (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)) ? 29 : 28
elsif month <= 7
month % 2 == 0 ? 30 : 31
else
month % 2 == 0 ? 31 : 30
end
end
The same unit tests can now be performed in under two seconds. I didn’t write the algorithm, it’s taken verbatim from the Rails ActiveSupport::CoreExtensions::Time::Calculations::ClassMethods module days_in_month method. That method appears to be the cause of the issue.
Testing Authorize.net with ActiveMerchant 1
I had some trouble testing Authorize.net with the excellent rails credit card processing gem ActiveMerchant. The documentation calls for the code ActiveMerchant::Billing::Base.mode = :test, however, this resulted in the following error:
The merchant login ID or password is invalid or the account is inactive.
To solve the problem, a key test with the String value true can be added to the gateway initialization hash, as follows:
if ENV['RAILS_ENV'] != 'production'
gateway = ActiveMerchant::Billing::Base.gateway(:authorize_net).new(
:login => "login",
:password => "transkey", :test => 'true')
else
gateway = ActiveMerchant::Billing::Base.gateway(:authorize_net).new(
:login => "login",
:password => "transkey")
end
Using this code, the account is placed into test mode when not run in production mode.
Multi Bit Shift Launch
I was finally able to launch my new product, Multi Bit Shift, a Flex multiple file upload applet complete with a Rails plugin to ease the integration. I learned a lot from this project, since this is the first that I have made use of project management software, in particular FogBugz, which I would highly recommend.
In particular, I learned that I grossly underestimated the amount of time required to produce proper documentation, the MBS website, and the product screencasts. Proper documentation is really what separates real, professional products from amateur contributions, so it is absolutely vital to dedicate whatever time is necessary to make sure everything is both well and thoroughly documented.
The website, and to a lesser extent the screencasts were also quite time consuming. I had my company, Compucated Solutions produce the design and integrate it with software that I wrote to manage the site. I am very pleased with the design and presentation at this point, but I must admit that I did spend considerable time writing and formatting content, as well as coding up the necessary software bits. I look at this kind of as an investment though, because when I go to release software in the future I have a very flexible engine that I can now quickly roll products out on.
The screencasts were also quite time consuming. I ultimately settled on the TechSmith’s Camtasia Studio product, as recommended by Jeff Atwood to produce the video. I am quite pleased by the results although I would like to be able to set the background color of the video files, and perhaps tweak the appearance a bit. While the software was a little pricey at $299 considering there are lots of competitors and viable alternatives, I ultimately settled on this particular product because it does what it does so very well. If you need to produce screencasts, seriously consider Camtasia, it is worth the premium. If you don’t need to produce screencasts, I suggest that you reconsider because they are a really excellent way to quickly convey complex information.
Besides just creating the screencasts, I also decided to make use of Amazon’s Simple Storage Service to host them. While I probably have ample bandwidth to host the screencasts on my equipment, I ultimately came to the conclusion that the users would have a better user experience if they were hosted by someone else. I have to say that, at this point, I am extremely impressed by the Amazon S3 service. It’s fast, reliable, flexible, easy to use, and inexpensive. I’m currently using the Firefox S3Fox plugin to manage the storage space. It really doesn’t get much easier.
All said and done, I believe I spent just as much, or even more time, documenting and launching this software than I actually did on the design and coding. In the future, I believe I’ll have to give much more thought in the product planning stages to the actual launch requirements (like a website, screencasts, docs, etc…) and the time required for their production.
Rails Boolean Field Helper
I wrote this some time ago and I thought it was worth reposting here, primarily so it would be easier for me to find. This details the handling of binary fields from front to back in Ruby on Rails.
Creation:
Active Record migrations are quite good at creating tables. The below migration will add table “table” to the db with a boolean field a_boolean when rake db:migrate is run.
class CreateTable < ActiveRecord::Migration
def self.up
create_table :table do |t|
t.column :a_boolean, :boolean
end
end
def self.down
drop_table :table
end
end
Boolean Form Field Select Helper:
The following line creates a select box with true and false represented by Yes and No. The currently selected value (while editing) is automatically selected.
<%= select('table', 'a_boolean', [["Yes",true],["No",false]]) %>
Validation:
This validation will confirm that the field is either true or false.
validates_each :a_boolean do |record, attr, value|
record.errors.add attr, 'is invalid.' if value != true && value != false
end
state_select and Rails 2.0.2 1
Because of a change in the workings of Rails 2.0.2, the excellent state_select plugin doesn’t work properly. Fortunately, the fix is really easy. After line 35, enter the following code, value = value(object).
This should give you a new to_state_select_tag, like this:
def to_state_select_tag(country, options, html_options)
html_options = html_options.stringify_keys
add_default_name_and_id(html_options)
value = value(object)
selected_value = options.has_key?(:selected) ? options[:selected] : value
content_tag("select", add_options(state_options_for_select(selected_value, country), options, value), html_options)
end
That change got the state_select plugin to work for me under Rails 2.
Update: This has been fixed in the latest version. If you are experiencing this issue, update to the latest version.