Fun with instance_eval

30 Jun 2009

Recently someone asked for a combination discount at the RailsKits store—he wanted to purchase both the SaaS Rails Kit and the Helpdesk Rails Kit to get his site rolling quickly. I didn’t have combo discounts at that time, but I figured that was a good excuse to build that feature into the store. :)

Previously when I have implemented combo discounts for my clients in their e-commerce platforms, I would do so by creating models that stored the combinations and the products that make up those combinations. These models would contain info like what quantities of each product were required, if one product out of a set could qualify for a combo, etc. It can get complicated fairly quickly.

This time, though, the client was me, and I’m comfortable with Ruby, so I decided to simplify the code by simply allowing the store administrator (me) to use Ruby to specify the rules for qualifying for a combo discount. In this case, instance_eval came in quite handy.

I already had a Coupon model, so I just added a text field named conditions to store the code that would be evaluated in the context of a cart instance. Then in my Cart model, after checking that a coupon was otherwise available, I ran instance_eval on the contents of that conditions field. That allowed me to create a coupon that requires at least two items in the cart with prices above $100 quite easily:

line_items.select {|i| i.unit_amount > 100 }.size > 1

It was fun to be able to implement something that can be hairy in just a few lines of code, thanks to the awesomeness of Ruby.

BTW, if you are interested in using that discount—15% off!—just enter the discount code ‘combo’ (without the quotes) during checkout while shopping for excellent Rails code.



Rails plugin directory revamp

22 May 2009

A lot has happened to the world of Ruby on Rails since the Rails plugin directory first launched back in 2005, and I have finally caught up. :) Of course I’ve been making changes all along the way, but today I’m launching a rewrite that makes the plugin directory current on all the latest and greatest.

Back when the site first launched, the state of the art Rails deployment was lighttpd with fastcgi. Ah, those were the days. :) Since then I’ve moved to lighttpd with mongrel, then nginx with mongrel, and now it’s running Apache with Passenger. For search, the best option back then was ferret, and let me tell you, I’ve gotten more than a few exception emails from ferret. But now the site is using sphinx for search, which I’ve been using in other apps for quite a while. Of course, some things don’t change. Even though I’m updating the UI, it’s still a freely available template, since I haven’t gotten much better at web design in the past 4 years. :)

The biggest change for me is due to something that didn’t exist in 2005: GitHub. Now that just about every plugin is hosted there, I wanted to make it super easy to get plugins listed on GitHub into the plugin directory, so now there’s a button you can use when creating a plugin that will take your GitHub url and suck in as much data as it can about your plugin, so you don’t have to do as much work to add it to the directory. I even have a bookmarklet you can use to publish your plugin while you’re looking at the GitHub page for your plugin: Publish plugin. Just drag that to your bookmarks bar, click it when you are looking at the GitHub page for any plugin, and a new window will pop up with the plugin information pre-filled for you. Thanks to the GitHub guys for their great API that makes that easy!

So enjoy the new Rails plugin directory—with extra-fresh Rails goodness and over 1,300 plugins in the database.



Exporting from a SaaS application

31 Mar 2009

Recently I had a request from a customer of my applicant tracking system application to do an export of all her data. This was one of those features that I had always planned to do, but not never got around to it, and eventually decided I would just handle it when it came up. Well, it finally came up, so it was time to deal with it. Let’s call it just-in-time feature delivery. :)

In Catch the Best, there are two sets of user data. The first set is in the database and is made up of notes, contact info, etc., about job applicants. The second set of data is the documents the candidates send in with their job applications, which are stored via the attachment_fu plugin. Exporting the first set of data is fairly simple, but the other set of data took a little more work. Here’s what I did.

First, to get the data out of the database, I decided to put the to_xml method provided by ActiveRecord to good use, redefining it in my various models to meet my needs. For example, I have this in my Submission model:


class Submission < ActiveRecord::Base
  def to_xml(options = {})
    super({ :include => [:source, :attachments] }.merge(options))
  end
end

And then in Attachment I have a similar to_xml method that spits out the relative path to the file, so that it can be matched up with the files that I will be including with the export.

For the resumes, I iterate over all the attachments that belong to the customer, adding them to a zipfile that the customer will download. It looks something like this:


Zip::ZipFile.open(zipfile, Zip::ZipFile::CREATE) do |zip|
  submissions.each do |submission|
    submission.attachments.each do |file|
      zip.add(file.relative_path, file.full_filename)
    end
  end
  zip.add(‘submissions.xml’, xmlfile)
end

That submissions.xml file at the end is actually the output of that to_xml call in the Submission model. All of the attachments and the to_xml dump are added to a single zip file, which the customer can then download. Add a couple of UI bits, and self-serve data exports from my SaaS application are good to go.

That’s much better than doing it by hand, and I got to wait more than a year after I launched Catch the Best before I spent time on that feature. Everybody wins. :)



Announcing the Helpdesk Rails Kit

25 Feb 2009

A new Rails Kit is now available: The Helpdesk Rails Kit makes it easy for you to add a support center to your existing Rails app, or even to just run a standalone support site along-side your existing Rails app.

You get an admin interface for you and other people on your team to see, route, and handle tickets from your customers and update your knowledgebase, and your customers get a web interface to keep track of their tickets and view your support articles. The Helpdesk Kit also provides email integration, so you can have your customers send email to your existing support email address and get responses back from that email address, while you and your team can still view, tag, and assign the tickets that come in via email using the web interface (which also has an ATOM feed, to keep you on top of everything).

If you’ve been wanting a support site for your Rails app, check out the Helpdesk Rails Kit. And, If you need some recurring billing for your Rails app, don’t forget about the Software as a Service Rails Kit. With these two Kits, it’s almost SaaS-in-a-box. :)



Another look at integrating Scribd with your Rails application

23 Feb 2009

Almost a year ago I wrote about integrating Scribd into your Rails application, and since then that feature has been working well in my applicant tracking system. Today, though, I got a request for information on how I display the documents that I send to Scribd, so I thought I’d share that, too. Read the rest of this entry »