Barefoot Development

SlideShowPro - XML attributes

I am using the SlideShowPro component in a Flash piece I am working on and so far it has been a great experience. This is a pretty solid as Sears component.

However, I have the need to extend the XML schema and include additional attributes on my image nodes. It can be done no problem, as discussed here on the SlideShowPro forums. BUT, I noticed that the component converts all attribute names to lowercase.

So, say you want to add an attribute containing the path to download the image, call it "downloadPath." Notice the uppercase P. When retrieving that attribute via the data Object created by SlideShowPro ( the name has to be all lowercase (i.e. I'm going to stick to just using all lowercase attribute names in the XML to thwart off confusion.

I was going to add this as a reply in the forums, however, they seem to be closed to new registrations?

Michael Krisher, Senior Developer, Barefoot
cross posted here


Custom Sorting in Ruby

I have been an expert Java developer for many years, but over the past year I've had the opportunity to use Ruby on Rails for a couple real projects. I'm really enjoying Ruby and hope to to use it more often in the future.

My current RoR project has several models with bi-directional has_many :through relationships where two models link to a third join model that has one or more additional property fields. For example, Users link to Albums through a Selections join model. The selections table includes fields for user_id and album_id, with an additional field that contains the rating each user gives to each album. (This example uses different entity names to protect the client.)

These relationships are illustrated (with simplication) here:

class User < ActiveRecord::Base
  has_many :selections, :dependent => :destroy
  has_many :albums, :through => :selections

class Album < ActiveRecord::Base
  has_many :selections, :dependent => :destroy
  has_many :users, :through => :selections

class Selection < ActiveRecord::Base
  belongs_to :user
  belongs_to :album

I needed to be able to list all the albums chosen by a user, sorted by album name. I tried this:

@user.selections.each do |selection|
# ...

but the album names were not sorted. I thought that the nifty option :order => 'name' would work on the has_many :through, but alas, it didn't. Then, my Java experience reminded me of the Comparable interface. It turns out that Ruby includes a very similar pattern, but it comes complete with Ruby nice-ness.

When you sort an Array (or anything Enumerable), you can override the <=> method of the Object class to provide your own custom sorting code. (Just like the equals() method in Java.) The <=> method returns -1, 0, or 1 to indicate whether the instance is smaller, equal, or greater than the other object. Here's the method I added to the Selection model to tell it how to sort:

def <=>(o)
   # Compare album name
   album_name_cmp = <=>
   return album_name_cmp unless album_name_cmp == 0

   # Compare user last name
   user_ln_cmp = self.user.last_name <=> o.user.last_name
   return user_ln_cmp unless user_ln_cmp == 0

   # Compare user first name
   user_fn_cmp = self.user.first_name <=> o.user.first_name
   return user_fn_cmp unless user_fn_cmp == 0

   # Otherwise, compare IDs
   return <=>

Then, just change the block slightly to use the sorted version:

@user.selections.sort.each do |selection|
# ...

If the model you're trying to sort is not already Comparable, you should add the line include Comparable to include the Comparable mixin. ActiveRecord objects are already Comparable.

Have fun writing your own custom sorting rules in Ruby! Leave a comment if you need more details.

Doug Smith, Senior Developer, Barefoot

Labels: , ,