Fun with instance_eval

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.

Comments