GreenStem - My New Company
Now that I have completed both LeagueSmart and OnlineListings I now have time for outside contracts. I am doing so through my new company GreenStem. If you have any work that you need done let me know and we can work something out.
LeagueSmart is Live
The LeagueSmart release was a very gradual one, just the way I like it. To be honest notifying thousands of people all at once about a new application is a little of the stressful side. Many tests can been written trying to ensure the app is as close to bug free as possible, but having an application with zero bugs is only possible in dreamland. That is what is nice about releasing something gradually. Bugs are bound to show up once different people start using the application in a much different way then you anticipated, and they did just that for me. Luckily they were fairly small issues and were able to be fixed quickly.
The release of LeagueSmart took about a week. I gradually notified groups (~400) of current SoftballSmart users on a daily basis, which allowed for any errors that were discovered to be fixed before most people saw them. I found doing it this way greatly reduced the tension build up when you are tailing the log files and the hits begin to come in.
If you are in charge of managing a league of any kind please check out LeagueSmart, and any feedback is always appreciated.
EdmontonOnRails
EdmontonOnRails is back with a vengeance! There was a previous attempt at getting Edmonton Rails developers together that didn’t make it too far, so hopefully things will be different this time around. The EdmontonOnRails site will be the place to keep up to date with news and upcoming events. If you, or others you know, live in Edmonton and want to join the group leave a comment below or email me (chris@chrisolsen.org) to let me know you are interested.
LeagueSmart soon to be beta

LeagueSmart is a web application that is designed to make creating league schedules and managing the stats as easy as pie. LeagueSmart is the upgrade of SoftballSmart, although the two will run in parallel for a while.
LeagueSmart is no longer created for just softball leagues, but will work for any recreational league. So far the application consists only of what is required for it to be useful, which is creating league schedules and keeping game scores. This may not sound like a lot, but anyone that has had to create a league schedule, will know that it can take a lot of effort to put together a schedule, and becomes a nightmare when a team backs out at last minute and the schedule has to be re-created. LeagueSmart automates the scheduling. To create the first schedule should not take a person any more than 10-15 minutes (depending on your team and game count), and recreating the schedule is even faster since you don’t have to re-add the teams, game locations etc.
Additional features will be added in the future, but right now I want to keep things as lean as possible to make sure that improving what currently exists is top on the priority list.
There are still a few more tests that I want to run before making it public, but I can say that things will be ready within a week.
Onlinelistings is Live

I am happy to announce the launch of Onlinelistings. The purpose of the site is to allow realtors to create professional web pages that are easy to use for them and their clients.
This project was one that took a little longer than I initially estimated due to some factors outside my control and others that I never handled the way I should have. Below are a few tips to increase your chances of success, that I failed to remember while working on the project.
-
Get the least amount of work done first
When working on even a small project the list of todos can begin to grow quickly and suddenly that small project becomes quite large. Features redefine the f-word ie. can really feature things up. What happens, is a good idea grows into something that seems to be required, which then results in the completion date being extended by a week or so. Add a couple more of these features and you have just added a month to the project. To prevent extended completion times determine what the core functionality is and work on nothing but that.
-
Establish a user base right away
Without users even the best application is worthless. So get the core done, get it on the web then get people interested. Receive input from the users then make improvements to what has already been done. The benefits of this is that you get users that are interested, you get feedback from a different perspective than your own and you have a solid base to expand on.
-
Ignore the 20 percent
There is always going to be the few, which includes you, that request the interesting features. Some of these suggestions may seem to make sense at first, but there is a good chance1 that the people that are requesting these features are the same people that purchase items like the vibrating knife to later discover that they don’t need it as much as they thought they would. Don’t be afraid to say no to certain requests. If interest continues to grow over time then it might be time to re-examine things.
Hopefully this reminder will help someone else from making the same mistakes that I did.
If you know any realtors that have a site that is hard on a person’s eyes I would appreciate it if you sent them my way.
1. This statement is backed by absolutely zero data
Installing Git on Ubuntu
I watched Scott’s great screencast on Git and figured I should make use of the old server that I have sitting around. Unfortunately, my install didn’t go as smoothly as Scott’s, mostly because the Ubuntu server edition has a few less libraries than the developer edition. So to make things a little smoother for others here are the libraries that I had to install.
sudo apt-get install build-essential tcl8.4 tk8.4 gettext
# expat wget http://superb-west.dl.sourceforge.net/sourceforge/expat/expat-2.0.1.tar.gz tar zxfv expat-2.0.1.tar.gz cd expat-2.0.1 ./configure make make install
# curl wget http://curl.linux-mirror.org/download/curl-7.18.0.tar.gz tar zxfv curl-7.18.0.tar.gz cd curl-7.18.0/ ./configure make prefix=/usr all make prefix=/usr all install
# zlib wget http://www.zlib.net/zlib-1.2.3.tar.gz tar -xzvf zlib-1.2.3.tar.gz cd zlib-1.2.3/ ./configure make sudo make install
# openssl wget http://www.openssl.org/source/openssl-0.9.8c.tar.gz tar -xzvf openssl-0.9.8c.tar.gz cd openssl-0.9.8c/ ./config --prefix=/usr/local/ssl-0.9.8c shared zlib-dynamic enable-camellia make depend make sudo make install
Now you should be able to install git
# git wget http://kernel.org/pub/software/scm/git/git-1.5.4.4.tar.gz tar -xzvf git-1.5.4.4.tar.gz cd git-1.5.4.4/ make MOZILLA_SHA1=1 prefix=/usr all sudo make MOZILLA_SHA1=1 prefix=/usr install
The steps above may not be perfect as I posted them after retracing my steps after a successful install. My fingers are crossed.
** Update:
Thanks to Sascha for pointing out the — double dash issue. That’s what I get for being too lazy to enclose the script within pre tags.
Hopefully this saves someone a little time.
My Apologies
Tonight I was working away at a Tim Horton’s, since it is a change from my normal working space (their coffee is really not very good), when I get a message on my cell phone from a friend. The message read “Uh-oh, you’re in trouble”, followed by a link. It has been quite a while since I felt that sick that fast.
A site that I created a couple days ago was on the front page of wilbit.com and not in a good way. The reason was a simple one, I just violated the 11th commandment.
I created a small app (~8-10 hours of work) to allow me to track my spending since tax time coming up and who wants to use a spreadsheet to enter data where a web application could do the same thing. So, of course, that is what I have to do.
I have this issue with creating apps that I can’t do it with no styles, it seems to through my focus out the door. I like to have things looking nice while creating. I didn’t feel like designing something since it would have doubled the time required on the app so I copied the beanstalk app layout.
After inserting some of my transactions I figured before I wasted too much time I should just make it a public app, because maybe, just maybe there is someone else out there that would use it, and after all I have a extremely slow site5 account that I already paid for a year upfront that I am not using, so why not. So I added the ability to create an account, made a couple of quick fixes and deployed.
I guess I didn’t put myself in the other person’s shoes to whom I copied from and I really really apologize for it. Sometimes when you get the deployment rush, even for small apps like this, your primary goal is to get it up on the sever and you lose sight of other important things.
The worst thing is that I only told three people about the app, two friends and my mom. Oh, the humiliation.
I wish I would’ve checked my email earlier and took care of things before the blog post was made, but that is a lesson to me in trying to manage my time better my keeping my email turned off while I am working.
Once again my apologies to Chris Nagle* and the team at Wildbit.
*Owns and operates Wilbit, that has created Beanstalk. Beanstalk is a really good app for keeping your projects on, and highly recommend it to anyone that hasn’t caught the Git bug that is going around.
Avoid Inline Javascript with Rails and jQuery
Rails is a great framework and one that allows someone that is new to it get started quickly. I am sure there is many of us that remember the 15 minute blog tutorial, and I must admit, that seemed pretty damn cool the first time I saw it. However after using rails for a while it didn’t take long for some of the automation scripts to lose their appeal. I am now beginning to feel the same in regards to ajax helper methods and .rjs files. They were great at the start because making something cool with rails didn’t require me to learn a javascript library, I was able to just dive right in.
So to get away from all the needless javascript that is auto-created and embedded in the rendered html I decided it was time to read up on one of the many javascript libraries that are available. Even though rails, by default, comes with Prototype and Scriptaculous, I decided to check out jQuery for reasons that are irrelevant to this post.
To quickly test to see how well jQuery would work with Rails I figured that, at the very least, it would have to allow me to do the following:
- Provide the same functionality that the link_to_remote helper function does.
- Allow for simple form data submissions, ie. a filter from a search box
- Enable complex form data submittals
So let’s create a simple project that will just allow us to create a contact list.
rails MyContacts
Now let’s create a table to hold the contact information
script/generate model contact first_name:string last_name:string email:string phone_number:string
And to allow us to get a quick start let’s create some sample data
script/generate migration contact_data
class ContactData < ActiveRecord::Migration
def self.up
Contact.create(:first_name => "Joe", :last_name => "Smith", :email => "joe@example.com", :phone_number => "555-3432")
Contact.create(:first_name => "Sally", :last_name => "White", :email => "sally@example.com", :phone_number => "555-8654")
Contact.create(:first_name => "Mike", :last_name => "Green", :email => "mike@example.com", :phone_number => "555-6944")
Contact.create(:first_name => "Mary", :last_name => "Brown", :email => "mary@example.com", :phone_number => "555-2346")
Contact.create(:first_name => "Alice", :last_name => "Black", :email => "alice@example.com", :phone_number => "555-7866")
Contact.create(:first_name => "George", :last_name => "Lucas", :email => "george@example.com", :phone_number => "555-1234")
Contact.create(:first_name => "Jim", :last_name => "Anderson", :email => "jim@example.com", :phone_number => "555-4464")
end
def self.down
end
end
Lastly, let’s create a controller
script/generate controller contacts index show
class ContactsController < ApplicationController def index @contacts = Contact.find(:all) end def show @contact = Contact.find(params[:id]) end def search filter = params[:filter] @contacts = Contact.find(:all, :conditions => ["first_name like ? or last_name like ?", "%#{filter}%", "%#{filter}%"]) render :action => :index end end
The first item in the required functionality list was to make simple get requests without using the link_to_remote. To do this lets show a list of the users with a link, that when clicked on will show their phone number and email. Below is the code that will allow for the list of contacts to be displayed. I also included the search form that will be used a little bit later.
<!-- contacts/index.html.erb --> <h1>My Contacts</h1> <%= link_to "Create Contact", new_contact_url %> <% form_tag search_contacts_url do %> Search By Name: <%= text_field_tag :filter %> <%= submit_tag "Search" %> <% end %> <ul class="contacts"> <%= render :partial => "contacts/contact", :collection => @contacts %> </ul> <!-- contacts/_contact.erb --> <li><%= link_to "#{contact.first_name} #{contact.last_name}", contact_url(contact) %></li> <!-- contacts/show.html.erb --> <h2><%= "#{@contact.first_name} #{@contact.last_name}" %></h2> <%= render :partial => "contacts/contact_details", :object => @contact %> <!-- contacts/_contact_details.erb --> <ul> <li>Phone #: <%= contact_details.phone_number %></li> <li>Email: <%= contact_details.email %></li> </ul> <!-- routes.rb --> map.resources :contacts, :collection => {:search => :post} <!-- web.css --> body {background-color:#9FDD8F;} #wrapper {margin:auto; width:760px;} #centre {float:left; background-color:white; width:760px; padding:15px;} .contacts {float:left;} #contact_details {float:left; margin-left:50px;} #contact_details dt {float:left; width:60px;} <!-- application.html.erb --> <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>My Contacts</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <%= stylesheet_link_tag "web" %> <%= javascript_include_tag "jquery-1.2.3.min.js" %> <%= yield :javascript %> </head> <body> <div id="wrapper"> <div id="centre"> <%= yield :layout %> </div> </div> </body> </html>
If we test what we have out you will see that it works, but having to go to a new page to view the contact’s information, then click the back button to return to the contact list makes me feel rather nauseous. So let’s make the changes to insert the ajax functionality and bring things up to the web 2.0 standards.
Before we get started we will have to download the latest version of jQuery, which can be found on the main page here. Save the file in the public/javascripts folder.
Next we will create a helper method that will allow us to easily insert our custom javascript into the HEAD tag of the page. I have to thank Ryan Bates for letting me know of this method.
# app/helpers/application_helper.rb def javascript(url) content_for :javascript do javascript_include_tag url end end
The two blocks of code above allow us to easily fetch the javascript within the js.erb files, since that is where we are going to put it. To insert the javascript file add the following at the top of the index.html.erb file.
<!-- index.html.erb --> <% javascript formatted_contacts_url("js") %>
This will generate the script tag that will make a request to the controller for the index.js.erb. To allow for this we will also have to update the index method in the Contacts controller. Now our dynamic javascript will be sent back to the client.
def index respond_to do |format| format.html {@contacts = Contact.find(:all)} format.js # returns the index.js.erb # Add this line of code end end
As was mentioned earlier, there were a few things that I wanted to make sure were do-able without too much work. The first one was to make an ajax request much like the link_to_remote helper function. So instead of directing a person to the contact details page, show the details on the contact list page. To do this we will have to make some updates to the controller code to allow it to handle the javascript requests.
def show @contact = Contact.find(params[:id]) respond_to do |format| format.html format.js {render :partial => "contacts/contact", :object => @contact} end end
As you can see, we are calling on the render method for the partial within the controller code, rather than from the rjs file, to where it normally resides. This will generate the html block of code that we will then insert into the DOM. Before we do that we have to create the javascript that will make the AJAX request, as well as handle the callback. To do this insert the following code in a new index.js.erb file.
// app/views/contacts/index.js.erb $(document).ready(function(){ $contact_details = $("<div id='contact_details'></div>").insertAfter($("ul.contacts")) $("ul.contacts a").click(function(){ $.get($(this).attr("href") + ".js", function(data){ $contact_details.html(data); }); return false; }); });
I will am only going to give a brief explanation of the javascript. If you do want to get up to speed with jQuery, this book is very well written and within a few hours you will know your stuff.
On line 2 we bind the DOM loaded event with the inline function ie. the remainder of the code. In line 3 I insert a div tag just after the ul tag to allow the search results to be shown. The reason for this is the div tag that is inserted will only be used to hold the data returned from the ajax request, so it really doesn’t make a lot of sense to hard code it into the html. Line 4 binds click events to all the links within the ul.contacts tag. Line 5 is the function that is bound to the links within the ul tag. This makes a GET request to the same url that is contained within the link to which the event is bound. The second parameter to the $.get() method is the callback function that will insert the returned data into the contact_details div tag.
So far everything is working nicely. We are able to easily view the details for all of our contacts. The next step is to make the updates to allow us to search for contacts via AJAX requests, which can be done with the following code.
First, we will have to update the index.js.html file.
//bind the ajax method to the form $("form").submit(function(){ $.post("<%= formatted_search_contacts_url('js') %>", $(this).find("input").serialize(), function(data){ $(".contacts").html(data); }); return false; });
Here we bind an inline function to the submit event of the form. The post function takes 3 parameters. The first is the url to post to. Since this code exists in an .erb file and can be dynamically rendered back to the client we are able to use one of the RESTful routes supplied by rails to create the url. Since we are making a javascript request we also have to properly format the url to allow the request to be properly handled by the server. The second parameter consists of the form data. There are a few different ways to pass the data, but the method used here is the easiest. The last parameter is the callback function that will insert the returned data into the page.
Before we go any further I should mention there is another way to do what was done above. There is an additional jQuery plugin that makes form submittal even easier that can be found here. To use this first download the file to the javascript directory, then add the additional javascript file to the head tag.
<%= javascript_include_tag "jquery-1.2.3.min.js", "jquery.form.js" %>Below is the code that will now allow us to make post requests. The nice thing about this method is that it makes it easier to bind multiple functions to be fired on the beforeSubmit and the success events. I think this code is pretty self-explanatory so I won’t bother going over it. If you want to use the second method mentioned replace the previously mentioned code with the following.
$("form").ajaxForm({ url: "<%= formatted_search_contacts_url('js') %>", beforeSubmit: function() {alert("This is where we would show our cool little spinner");}, success: function(data){ $(".contacts").html(data); return false; } });
With these updates we are now able to search our contact list via AJAX, but there is one catch. If you perform a search to filter the contacts, then click on a contact to view their details you will then be directed to the details page. What is the reason for this you ask? Since our javascript is no longer embedded within a onclick in the link tag that means that responsibility has fallen onto our shoulders, but there are a couple ways to fix this.
The first way is to bind the new items returned in the search results. This method would require a little re-factoring of our current code and isn’t overly hard to do, but there is an easier way. Thanks to event-bubbling all we have to do is bind the event to a parent of the links rather than the links themselves. Update the index.js.erb file to include the following in place of the previous block that bound the click events to the links.
//bind ajax to view the contact details $("ul").click(function(event){ $link = $(event.target); $.get($link.attr("href") + ".js", function(data){ $contact_details.html(data); }); return false; });
Now all the links works as they should after a search is performed.
The last item on my requirement list was to submit a more complex form. As it turns out it can be done using the same method as used in the search example, which is pretty cool. So I am pretty sure that it is safe to avoid repeating myself in another form example.
This wraps up this post regarding avoidance of inline javascript. The html that is returned to the user is clean and it will prevent the user from downloading needless amounts of data in the event that they are accessing the site and have javascript disabled or are unable to use javascript.
Learn RubyOnRails in 30 minutes
Recently, there was a couple articles posted (here and here), regarding how long it takes for a person to become familiar with a toolset. In light of these articles I found this job advertisement today and thought it was rather amusing.
Qualifications:
- A thorough understanding of ASP.NET (or a similar server-side web platform, such as J2EE, PHP or Ruby on Rails), not only the language, but the community, libraries, resources and best practices
- Experience with CSS, DHTML and JavaScript
- Experience with AJAX (an asset)
- A knack for usability design
- A working familiarity of databases (SQL & Oracle)
- Able to learn in half an hour, given access to a web browser, anything on this list
- Familiarity with Macs (an asset)
I am really kickin’ myself for spending all that time reading books and working on whatever I could to help me learn a new language/framework, when all I had to do was to check out the internet for 30 minutes.
Google Charts with Rails
Nothing beats some nice charts to dazzle your clients. I guess this is another addition to a couple of previous posts that go over various charting tools that can be found here and here.
If you haven’t checked out Google Charts go here to check out the API. To use Google’s charts you have to encode the data with one of the three allowable formats.
- Simple encoding uses the alphanumeric characters (A to Z, a to z, and 0 to 9) where A represents 0, B represents 1, and so on up to 9, representing 61 to provide a resolution of 62 different values. Allowing five pixels per data point, this is sufficient for line and bar charts up to about 300 pixels. Simple encoding is suitable for all other types of chart regardless of size. This type of encoding results in the shortest URL.
- Text encoding uses floating point numbers between 0.0 and 100.0 to provide a resolution of 1,000 different values. Allowing five pixels per data point, integers (1.0, 2.0, and so on) are sufficient for line and bar charts up to about 500 pixels. Include a single decimal place (35.7 for example) if you require higher resolution. Text encoding is suitable for all other types of chart regardless of size.
- Extended encoding uses pairs of alphanumeric (plus a few others that are discussed later) where AA represents 0, AB represents 1, and so on up to two periods (..) representing 4095 to provide a resolution of 4,096 different values. This is best suited for large charts with a large data range is required.
The good thing is, is that there are a few tools that are available for Rails that will do the work for us. I fooled around with the top two of them, although I am a little unsure of the status of either.
I had some issues with Google Charts on Rails as the labels would not render as they were supposed to. After looking at the source code it seemed that, by all the #TODO… comments that the development on this plugin may be discontinued.
With the first not working as I thought it would I moved onto the second. Google Charts worked very nicely and within a couple of minutes of reformatting the reporting data I had some pretty cool charts.
Since Google Charts works I never even bothered to test gchartb although I will put it on my to-do list.
So let’s create some graphs. First thing that we have to do is install the GoogleCharts gem
sudo gem install googlecharts
Once that is done we will have to add the following to the top of our controllers/application.rb file. You could also just add this line to the controller(s) that contain reporting methods.
require "gchart" #the line to add class ApplicationController < ActionController::Base ...
For the tests I created a Seller and Sale models with the following migration files.
# 001_create_sellers.rb class CreateSellers < ActiveRecord::Migration def self.up create_table :sellers do |t| t.string :name t.timestamps end end def self.down drop_table :sellers end end # 002_create_sales.rb class CreateSales < ActiveRecord::Migration def self.up create_table :sales do |t| t.decimal :amount, :precision => 10, :scale => 2 t.date :sold_on t.integer :seller_id t.timestamps end end def self.down drop_table :sales end end
And of course to test out the charts we will need some test data.
# 003_test_data.rb class SampleData < ActiveRecord::Migration def self.up # create some sellers john = Seller.create(:name => "John") susan = Seller.create(:name => "Susan") # add sales to sellers [john, susan].each do |seller| (0..20).each do |i| Sale.create(:amount => rand(1000), :seller_id => seller.id, :sold_on => DateTime.now + i.days) end end end def self.down end end
Now we have to be able to access the data in a format that will work well with charts. To do this I created a sales_report method within the Seller model.
class Seller < ActiveRecord::Base def sales_report data = [] labels = [] Sale.find_all_by_seller_id(self.id).each do |s| labels << s.sold_on.to_date.strftime("%B %d") data << s.amount end {:labels => labels, :data => data} end end
That is it for the dirty work, it is smooth sailing from here (said with a lot of sarcasm).
All we have to do now is access the data from the controller.
class SalesReportController < ApplicationController def show @report = Seller.find(params[:id]).sales_report end end
and make sure that the routing is set up by adding the following to the router.rb file
map.resources :sales_report
To display it on the page I created a show.html.erb file with the following code.
<%= image_tag Gchart.bar(:title => 'Sales', :size => '600x200', :data => @report[:data], :custom => "chbh=6,2,0") %>
I did leave out the labels on the chart. Since I had so much data they were taking up way too much room. To add the labels you would just append :labels => @report.labels to the arguments in the bar method call.
Here is the final result.

It is pretty cool that Google provides us with the service free of charge. The downfall is that there is a daily limit of 50,000 charts that can be generated per site. I can’t think of anything that I have worked on that would exceed that number, but things can change. The other issue is that Google has control and at any time could discontinue supplying the service. Personally I can’t picture Google doing something like that, but anything can happen.
Although Google’s API and GoogleCharts make things pretty easy I hope this helps a couple of people.
Technorati Tags: charting, rubyonrails

