Tuesday, September 16, 2008

Google Analytics Campaign URL Encoding with Ruby on Rails

So we're launching a couple pages that we wanted to enrich the links and encode them with the Google Analytics campaign tracking data. (If you're not familiar with it, you can take a look at the url builder here).

Basically, you create a campaign source (email, ad, or whatever) a medium and a name and it will build a url for you.

All of the links on the page we were building had the same source and campaign name, but different medium names.

So at the top of the page in the view (I thought about doing this in the controller, but for our purposes it is a per page kind of thing) I added a little erb code:
<% source_link = 'blah' medium_link1 = 'link1' medium_link2 = 'link2' campaign_link = 'nameofcampaign' %>

Now, when you have a link_to helper in your page, add the following parameters after the :action

:utm_source => source_link, :utm_medium => medium_link1, :utm_campaign => campaign_link

This way, if you want to update the URL encoding for Google Analytics for a different campaign down the line, it's a matter of just changing the variables at the top of the page, rather than going down through the whole view to change every source and every campaign link.

Anyways, I felt proud of myself to be a little bit more DRY in my view with Google Analytics Campaign URL encoding.

Using before_save in the model

I was doing some refactoring of our email subscription functionality and I added a table column to include a hash of the email address which I would use in the unsubscribe process.

So I created a new migration that added the column and calculated the hashes for the existing email addresses in the table, however, it was not automatically creating the hashes using the current functionality.

So, it's a pretty simple call in the model, a function called before_save.

My model file ends up looking like this, which creates the hash right before it saves the email address when someone subscribes.
before_save :add_email_hash

def add_email_hash
self.email_hash = Digest::SHA1.hexdigest(self.email + "addsometexttomakeithardtorecreate")

And that's it! An addition to the model file which is supposed to handle this sort of thing, rather than the controller.

Thursday, August 28, 2008

Load Sample Data into Dev Database

I needed to load the same type of data into my rails app and then mess around with it to see if my changes broke anything, and the reset the data easily to a standard data set.

Originally I was using the rake command:

rake db:fixtures:load

which loads all of the fixtures you currently have in /test/fixtures.  This works okay, except the test fixtures that I have in that directory are specifically written for unit tests and don't always have the all the fields filled out because I'm only testing certain things.

Basically what I was trying to do was create some fixtures somewhere else that would hold real data that I could populate to my website, try out new migrations and different things on the site and then be able to refresh back to the start after manipulating the database via my website.

I also tried making a data-only migration, which works, but I didn't want to really do it that way, because the data is only for my dev environment.

So what I ended up doing was something similar to what I found here: http://quotedprintable.com/2007/11/16/seed-data-in-rails

I created a custom rake command under /lib/tasks (if there isn't a file there already, create one called "database.rake")

Then in the file add the following code:

namespace :db do
desc "Load sample data fixtures (from db/fixtures) into the development environment's database."
task :sample => :environment do
if RAILS_ENV == 'development'
require 'active_record/fixtures'
Dir.glob(RAILS_ROOT + '/db/fixtures/*.yml').each do |file|
Fixtures.create_fixtures('db/fixtures', File.basename(file, '.*'))
puts "You cannot run this from the production environment."

The basic changes from the Quoted-Printable article that I made was to add the check for the development environment, as you wouldn't want to accidentally run this from your production server and overwrite your database with your sample data.

Now create a directory in /db called fixtures add all your .yml files for each of your models into the /db/fixtures directory and every time you need to refresh your development database to your sample data, simply run the following rake command:
rake db:sample

Pretty cool, huh?