eddorre

Manually Updating RubyGems

Sunday February 01, 2009 01:41 | comment icon 0 Comments

I just did a deployment of my blog and came across a nasty little problem. The deployment in question required that a database migration be run in order to create a new table. Unfortunately, when I tried to run the rake db:migrate command it complained that I was missing a gem. So I tried to install the gem using the command: sudo gem install [gem name].

Here is where the problem comes in. Since I was running RubyGems version 1.0.1, trying to install or update any gem (including updating itself!) would hammer my poor little web server. I think I waited at least 5-10 minutes before killing the process.

This happens because there is a bug in earlier versions of RubyGems. Updating to a newer version (at least 1.2.0) will take care of the issue. Unfortunately, since downloading the RubyGems update will kill the server using the gem update command, I had to install it manually.

First thing is first; download the gem manually using WGET (at the time of this writing the latest RubyGems is at 1.3.1.


wget http://rubyforge.org/frs/download.php/45904/rubygems-update-1.3.1.gem

Once it has been downloaded, install it:


sudo gem install rubygems-update-1.3.1.gem

Finally, update RubyGems:


sudo update_rubygems

If everything went OK, you should see 1.3.1 when running the command gem -v.

Once RubyGems was updated, downloading a single gem was almost instantaneous.

Released Tagging Feature for Site

Sunday February 01, 2009 01:55 | comment icon 0 Comments

I think the last new feature was Gravatar support way back in September of 2008. Now I’ve finally gotten enough free time to release a couple of new features. The first is linkable tags on post pages. I’ve had the ability to add tag for a while when creating a new post and they can be seen on the homepage and on post specific pages but they haven’t been linkable until now. Click on a tag and see what other posts have been marked with that tag.

Eventually I’ll add some sort of tag cloud so that one can see the most popular tags but that’s an update for another day.

Released Subscriptions Feature for Posts on Site

Sunday February 01, 2009 02:15 | comment icon 0 Comments

Having the ability to allow users to subscribe to a post (and therefore getting email updates when someone adds a follow-up comment) is something that I’ve been wanting to implement ever since I rolled out the first version with Ruby on Rails.

I think I first started the initial implementation of a subscription engine a few months back but it was extremely buggy and I was not satisfied with the underlying code. A couple of weeks ago, I dove in again and hacked a working version.

The implementation worked, but I was unhappy with the underlying code as it was based on code that I had written years ago. Now that my skill set has improved, I decided to rip out most of what was there and code up a cleaner version of the workable code.

After some rigorous testing, I’m finally happy with the implementation and the underlying code.

So how does it all work? Well, it’s simple really. If you want to be notified (by email) of follow-up comments to a post, click the Subscribe via email checkbox and post your comment. You’ll receive an email confirmation that let’s you know which post you’ve subscribed to. If someone posts a follow-up comment, you’ll get an email notification.

If you don’t want to be notified anymore, there is an opt-out/unsubscribe link on the emails that are sent out. Follow that link and the subscription to that specific post is terminated.

Object#type Errors with Single Table Inheritance

Tuesday February 03, 2009 23:09 | comment icon 0 Comments

Everybody probably already know this but what the hell. I was working on some code recently using Single Table Inheritance and was getting errors in the console and log when comparing the type field.

Before I get into the error itself and what I’m doing to correct it, a little background on Single Table Inheritance. Suppose you have employees in your database and you have two employee types; managers and staff.

You might have the following model objects:


class Manager < ActiveRecord::Base
end

class Staff < ActiveRecord::Base
end

And in the database, you’d have two separate tables; one for managers and one for staff. This is fine if the Manager table and the Staff table differ greatly from one another, but if they are identical with the exception of the type (Manager or Staff) then they can be combined in one table and be referenced in Rails using Single Table Inheritance.

This is done by having one class that Manager and Staff inherit from:


class Employee < ActiveRecord::Base
end

class Manager < Employee
end

class Staff < Employee
end

Now you can have one table, Employee, with a type column that differentiates that two. For example:

id type full_name phone_number
1 Staff Joe Jukem 5035551212
2 Manager Joe Blow 7025551212

Now here is where the problem comes in. Apparently “type” shouldn’t be used in your code. So when you’re doing something like this:


x = Employee.find :first
if x.type == Manager
   do something here
end

You’ll get a message that reads: warning: Object#type is deprecated; use Object#class instead. Now, obviously, the fix is to use something like this:


x = Employee.find :first
if x.class == Manager
   do something here
end

That works, but I like the more readable version using the is_a? method. For example:


x = Employee.find :first
if x.is_a?(Manager)
   do something here
end

Buildin' the Blog: Part 5 - Refactoring

Sunday February 15, 2009 21:58 | comment icon 0 Comments

It’s been a long time since I posted something in this series, almost 3 years to be exact, and it’s about due.

One of the things that developers do when they are new to the MVC paradigm/Rails is to litter their controllers with all sorts of business rules code. This isn’t a fault really. For beginners it’s a way to get your app and running quickly.

As a developer matures with the MVC paradigm, they begin to see that there is a better way to do things (think Fat Model/Skinny Controller). That certainly was the case with me.

For instance, the create action of my blog’s comment controller (the heaviest action by far) weighed in at a hefty 61 lines of code. After doing a bit of refactoring, my controller has dropped to 25 lines of code. Still not perfect, but all of the comment processing code has been moved into the model.

Let’s take a look at how and why I made the changes.

First thing is first. Since I’m using the Akismet web service to check for comment spam, I need to track the referrer, the IP address of the client, and the User Agent.

I used to have a line of code in the create action that got this information by calling a method in the Application Controller.


options = get_browser_info

That method was defined as:


def get_browser_info
  options = { :ip_address => request.env["REMOTE_ADDR"], 
                :user_agent => request.env["HTTP_USER_AGENT"], :referer => request.env["HTTP_REFERER"] }
end

This worked, but it lacked a little sophistication.

The new method in the Application Controller:


def fetch_browser_info
 @browser_info = { :ip_address => request.env["REMOTE_ADDR"], 
  :user_agent => request.env["HTTP_USER_AGENT"], :referer => request.env["HTTP_REFERER"] }
end

Now in the Comments controller, I can run a before filter on the actions that need this:


before_filter :fetch_browser_info, :only => :create

Unfortunately, the old Akismet plugin that I was using, ror_akismet, enforced the use of extra methods in the controller. I changed this up, by copying the akismet.rb file to my lib directory and removing its dependence on the controller. And yes, I know that ror_akismet is the old library file and rakismet is the replacement. At the time, I didn’t want to install and futz with the new plugin.

That allowed me to pull this entire code block:


if is_spam?(:comment_content => @comment.body, :comment_author => @comment.name, 
                :comment_author_email => @comment.email, :user_ip => @comment.ip_address, 
                :referrer => @comment.referer, :user_agent => @comment.user_agent)

That now goes into the model. With a code block that looks like this:


if is_spam?( { :comment_content => self.body, :comment_author => self.name, :comment_author_email => self.email, :user_ip => self.ip_address, :referrer => self.referer, :user_agent => self.user_agent }.merge(self.akismet_attributes))

That’s it for this edition of Buildin’ the Blog, but I’m not done rebuilding my Comments create action. In the next part of the series, I’ll cover how to access variables that aren’t part of your Model’s attributes (table columns) and a quick note about security.

Twonky Media Server 5.05 Up and Running

Saturday February 28, 2009 18:36 | comment icon 0 Comments

A year ago I posted an article on how I stream videos and music to my Xbox 360 using Linux and PacketVideo’s TwonkyMedia DLNA server.

In the year and a quarter since I posted the article a few things have changed. I picked up a PS3 which also allows me to stream music and videos to it and the new version of the TwonkyMedia server software was released. Unfortunately, the new version, version 5, broke my existing setup. So much so that I had to revert back to using 4.4.11.

After upgrading to the latest version, I setup the content directories that I wanted it to scan and it would never pick up anything and therefore no streaming. This afternoon, after poring through their forums (their actual support is terrible), I downloaded their beta release of 5 (version 5.055 to be exact) and tried to get it running again. No go.

I gave up, uninstalled version 5 and went back to version 4.4.11; at least for a couple of hours. Fortunately for me, my determination to solve problems is almost otherworldly.

In my instance, the problem was occurring because I had my media in the /var directory (/var/media/music and /var/media/video to be exact). For some reason, version 5 of the software refused to read any media from this location. Quite irritating.

The server was reading media from other locations and that was my clue that the server was working, just not reading from the /var directory. Moving all of my media from one location to another would be a pain in the ass, so using a tip from a forum poster I tried creating a symlink (aka alias) from my media directories to my home directory with the following commands:


ln -s /var/media/video /home/carlos/video

Once that was done, I put in the new content directories into Twonky (/home/carlos/video and /home/carlos/music) and then restarted the server. After restart I told it to re-scan the content directories and it finally recognized my media.

Now if only it could stream Hulu…

end kanji