captured sparks

Archive for 2008

Busy times

I haven’t had much opportunity to post here recently due to some travel and a mix of work on my own projects and work for clients. Aside from my development work, I also maintain a few websites and the updates and maintenance for these have been coming thick and fast.

One of my own projects is approaching fruition. It’s a small application that allows people to review coffee shops that are local to them or that they visit. The idea came following a trip to Hull where I had about 5 hours to kill and there was no way to find details of a good coffee shop where I could spend a few hours. I suppose I hope it may help unearth some gems and stop people heading for the nearest Starbucks or Costa.

The application uses the Google Maps API and the GeoKit plugin to geocode the location of coffee houses. I think this is the type of application that really suits having a mobile version and once the web version is sufficiently complete, I’ll work on producing a mobile friendly version. There is quite a bit to do, but I’m going to push it live in the next month and hopefully get some feedback that will drive continued development.

I also hope to write up a bit more detail on ActiveMerchant and PayPal as I note from the logs that the entry on that topic has received quite a bit of traffic and I think it is definitely a topic that could do with more documentation.

South Beds RSPCA

Background

The client needed an update to an already existing site that would enable them primarily to update the animals they had available for foster or rehoming. The redesigned site enables the local volunteers to upload details of cats, rabbits and guinea pigs that are available. They can also update their upcoming events from an easily accesible administration area.

ActiveMerchant, Paypal and Rails

I’ve spent most of the past week playing with ActiveMerchant and Paypal in order to implement recurring billing for my app.

After a false start with Datacash and some fumbling in the Paypal Sandbox, I got started with a test account for Website Payments Pro (UK). This has the benefit of using Paypal as your gateway service and also as your merchant account. The fees for processing are slightly higher than other gateways but I find the all in one solution worth it so far.

I should mention at this point that Cody Fauser’s ActiveMerchant PDF from PeepCode was invaluable in giving me a start to integration. Although the book is geared towards a straightforward purchase (rather than recurring billing), the code was a great starting point. Thankfully, the ActiveMerchant library is very well commented and easily understandable.

In brief, to setup the recurring billing (implemented through Subscription model), an account is created using the subdomain as account key model. If the account is a paying account, the user is redirected to a secure page to enter their credit card details and create the subscription. The credit card information, amount to be billed and frequency are passed to Paypal in the following form:

Subscription.recurring(amount, credit_card, options = {:ip => request.remote_ip})

This calls a method on the Subscription class which sends the data to Paypal. If a successful response is received, the response and other information is stored in the database.

In terms of updating the subscription, this is easily done with the AM library by sending the profile id (which is returned by Paypal when recurring billing is set up) along with the recurring billing request. Using this method, credit card details, payment amount and frequency can be simply changed.

I’m more than happy to share the code I’m using if you want to leave a comment.

Intaeco goes live

Due to pressing issues at work, I haven’t had the chance to say that Intaeco has gone live.

The company sells environmentally friendly plumbing and heating products such as solar heating systems. The site is static in nature aside from some PHP for the contact form and jQuery is used for the javascript effects.

A little bit on Growl and Autotest

There’s not a lot that I can say that hasn’t been said already on this subject. I’ve managed to get this working tonight via a combination of John Nunemaker and Aisle Ten.

John’s blog entry is a great high level overview of how to get it to work and Aisle Ten’s post will come in very useful if you run into any problems.

Creating monthly archives in Rails

Whilst creating my own blog software has made me realise how little I needed compared to the vast functionality of readily-available software, one of the things I did want was a monthly archive view.

The first thing I did was create a method in the Entry model that would assign each entry an “archive link” consisting of the month and year in which the entry was created:

class Entry < ActiveRecord::Base

after_create :create_archive_link
...
def create_archive_link
  month = self.created_at.strftime("%B %Y")
  month = month.downcase.sub(/[ ]/, "")
  self.month_year = month
  self.save
end

I have to confess at this point that I broke from the RESTful conventions that I try to employ and created a monthly_index method in the entries controller:

def monthly_index
  @entries = Entry.find_all_by_month_year(params[:month])
  @entry = @entries[1]
  @all_entries = Entry.find(:all)
end

For the blog index, I then list the monthly archives using the following code:

<ul>
  <% @all_entries.group_by(&:month_year).each do |month, entries| %>
    <li><%= link_to "#{month} (#{entries.size})", monthly_archive_url(month.downcase.sub(/[ ]/, "")) %></li>
  <% end %>
</ul>

This code does several things in a short space of time:

1) Groups each entry by a defined month_year method resulting in a hash keyed on the month_year method

2) Prepares to iterate through the hash based on the month_year key

3) Lists the month name and the number of posts in that month with a link to a monthly_archive_url route that is defined in routes.rb

In routes.rb, the following route is defined:

ActionController::Routing::Routes.draw do |map|
...
  map.monthly_archive 'entries/archive/:month', :controller => 'entries', :action => 'monthly_index'
...
end

I think the code could be cleaned up a little bit by defining more methods in the model. Just writing this has made me think that I should define a method to convert the archive link of february2008 back into February 2008.

What I have found is that writing a lot of the code needed to run an effective blogging platform is not particularly complicated when the function needed is broken down into a series of steps.

About the sidebar

I’ve add a sidebar to the individual blog entry pages so that I can let visitors know that we do some web design.

Just to confirm that I haven’t left off my ruby output tags. The idea of using variable names was inspired by Wil Wheaton and the auto-responder he used to have.

Dynamically generating a sitemap for Google

One of the issues I encountered with my previous Rails application was adding a sitemap to the root directory so that I could use Google’s Webmaster Tools. As I was not under a deadline for sparky, I was able to dedicate some time to the issue.

I figured the easiest way to create the sitemap was to use Rails’ built-in XML builder to dynamically generate the sitemap when requested by Google. This has the advantage of picking up every new blog entry.

First was the controller. In order to keep everything segregated and RESTful, I created a sitemaps controller with one action:

class SitemapController < ApplicationController

  def sitemap
    @entries = Entry.find(:all)
    @jobs = Job.find(:all)

    respond_to do |format|
      format.xml { render :layout => false }
    end
  end

end

I retrieve all the dynamic information in the controller, which is then passed to the view file. Creating the view was a lot of trial and error, particularly in terms of getting it to match the sitemap specification. Here though is the final view file split into chunks for commentary purposes.

base_url = "http://www.capturedsparks.com"
xml.instruct! :x ml, :version=>"1.0"
xml.tag! 'urlset', "xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9" do

This sets the header information in the resulting xml file as required by the sitemap specification.

for entry in @entries do
  xml.tag! 'url' do
    xml.tag! 'loc', "#{base_url}#{generate_url(entry)}"
    xml.tag! 'lastmod', entry.updated_at.strftime("%Y-%m-%d")
    xml.tag! 'changefreq', 'monthly'
    xml.tag! 'priority', '0.8'
  end
end

This iterates through the blog entries, which are contained in the @entries variable set in the controller. This is then followed with identical code for the @jobs variable.

For each of the static pages (including the blog and job indexes), I use the following code assigning them higher priorities than the individual blog and job entries.

xml.tag! 'url' do
    xml.tag! 'loc', "http://www.capturedsparks.com/about/"
    xml.tag! 'changefreq', 'monthly'
    xml.tag! 'priority', '1'
end

The resulting xml file can be seen here.

The need to know Ruby

As part of the development of my app, I had a need to display various different categories of to-do items – complete, overdue and “normal”.

I was using a method in the Todo class similar to the following to create these categories:

def self.find_overdue
  overdue = Array.new
  items = find(:all)
  for item in items
    if item.overdue?
      overdue << item
    else
    end
  end
  overdue
end

I was reading through the online Ruby documentation on another issue and came across a nice method in the Hash class: reject. This acts as a “delete if” method and can substantially reduce the code above:

def self.find_overdue
  items = find(:all)
  items.reject { |i| i.not_overdue? }
end

The “not_overdue” method is defined separately in the Todo class. I think this definitely shows the importance of knowing the Ruby language and equally demonstrates its power.

The cool stuff has to wait

As I sit here, all sorts of ideas are popping into my head that would be awesome to implement for my upcoming app. Unfortunately, they need to go on the back-burner.

I started work on the app yesterday afternoon and am still in the process of creating my models and controllers to give a basic functionality. Whilst I do enjoy working in Rails, this is the boring bit. I can’t wait until I can really get into creating my own methods and putting some of these ideas into practice.

Next Page »« Previous Page