AJAX Queuing in Piggybak
AJAX is inherently asynchronous; for the most part, this works fine in web development, but sometimes it can cause problem if you have multiple related AJAX calls that are asynchronous to eachother, such as the use case described in this article.
In Piggybak, a Ruby on Rails open source shopping cart module developed and maintained by End Point, the one page checkout uses AJAX to generate shipping options. Whenever state and zip options change, the shipping address information is sent via AJAX and valid shipping methods are returned and rendered in a select dropdown.

Event listeners on the state and zip code inputs trigger to generate shipping options via AJAX.
While working on development for a client using Piggybak, I came across a scenario where AJAX asynchronous-ity was problematic. Here’s how the problematic behavior looked on a timeline, picking up as the user enters their shipping address:
- 0 seconds: User changes state, triggers AJAX shipping lookup with state value, but no zip code entered (Let’s refer to this as AJAX REQUEST 1).
- 1 second: User changes zip code, triggers AJAX shipping lookup with state and zip value present (Let’s refer to this as AJAX …
javascript ecommerce jquery piggybak rails
Company Presentation: Ecommerce as an Engine
Today, I gave the presentation to my coworkers entitled “Puppies & Ecommerce as an Engine”. The presentation is strongly coupled with my work on Piggybak, and includes a discussion of traditional ecommerce platforms versus a lightweight ecommerce approach through modularity (Rails Engine). It also provides some code examples as how this does work in Piggybak.
Below are a few more related articles to my work on Piggybak. Check them out!
ecommerce piggybak rails spree company
Three Things: Times Two
It’s been a while since I’ve written up a “Three Things” article where I share a few featured web development tidbits picked up recently. So I made this a double episode!
1. event.stopPropagation() and event.stopImmediatePropagation()
I recently came across these two methods in jQuery, described here and here. Both of these methods [prevent the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event]. In my web application, my $(‘html’) element had a listener on it, but I added specific listeners to children elements that when clicked on calls event.stopPropagation to cancel the event on the $(‘html’) element. See the code below for a simplified example:
jQuery(function() {
jQuery('html').click(function() {
jQuery.hideSomething();
});
jQuery('.popup').click(function(event) {
event.stopPropagation();
});
})
2. alias_attribute
The alias method in Rails is one that I use frequently. But I recently came across the alias_attribute method as well. This might make the most sense to use when using shared views for multiple models with varying attributes.
3. Excel behavior in …
jquery rails tips
Cannot parse Cookie header in Ruby on Rails
Yesterday I resolved a client emergency for a Ruby on Rails site that continues to leave me scratching my head, even with follow-up investigation. In short, the emergency came up after an email marketing campaign was sent out in the morning, and resulted in server (HTTP 500 Status Code) errors for every customer that clicked on the email links. Despite the fact that Rails exception emails are sent to the client and me, the errors were never reaching the exception email code, so I was unaware of the emergency until the client contacted me.
Upon jumping on the server, I saw this in the production log repeatedly:
ArgumentError (cannot parse Cookie header: invalid %-encoding (...)):
ArgumentError (cannot parse Cookie header: invalid %-encoding (...)):
ArgumentError (cannot parse Cookie header: invalid %-encoding (...)):
The URLs that the production log was complaining about had a bunch of Google Analytics tracking variables:
- utmcmd=Email
- utmcct=customeremail
- utmccn=New Site Sale 70% off
- etc.
After a user visits the site, these variables are typically stored as cookies for Google Analytics tracking. Upon initial investigation, the issue appeared to be triggered from any Google …
analytics ecommerce piggybak rails
Enforcing Transaction Compartments with Foreign Keys and SECURITY DEFINER
In support of End Point’s evolving offering for multi-master database replication, from the precursor to Bucardo through several versions of Bucardo itself, our code solutions depended on the ability to suppress the actions of triggers and rules through direct manipulation of the pg_class table. Most PostgreSQL database developers are probably familiar with the construct we used from the DDL scripts generated by pg_dump at one time.
Disable triggers and rules on table “public”.“foo”:
UPDATE pg_class SET
relhasrules = false,
reltriggers = 0
FROM pg_namespace
WHERE pg_namespace.oid = pg_class.relnamespace
AND pg_namespace.nspname = 'public'
AND pg_class.relname = 'foo';
Re-enable all triggers and rules on “public”.“foo” when finished with DML that must not fire triggers and rules:
UPDATE pg_class SET
reltriggers = (
SELECT COUNT(*) FROM pg_trigger
WHERE pg_class.oid = pg_trigger.tgrelid
),
relhasrules = (
SELECT COUNT(*) > 0
FROM pg_rules
WHERE schemaname = 'public' …
bucardo database postgres
PL/Perl multiplicity issues with PostgreSQL: the Highlander restriction
I came across this error recently for a client using PostgreSQL 8.4:
ERROR: cannot allocate multiple Perl interpreters on this platform
Most times when you see this error it indicates that someone was trying to use both a PL/Perl function and a PL/PerlU function on a server in which Perl’s multiplicity flag is disabled. In such a case, only a single Perl interpreter can exist for each Postgres backend, and trying to create a new one, as happens when you execute two functions written in PL/Perl and PL/PerlU, the error above is thrown.
However, in this case it was not a combination of PL/Perl and PL/PerlU — I confirmed that only PL/Perl was installed. The error was caused by a slightly less known limitation of a non-multiplicity Perl and Postgres. As the docs mention at the very bottom of the page, “…so any one session can only execute either PL/PerlU functions, or PL/Perl functions that are all called by the same SQL role”. So we had two roles both trying to execute some PL/Perl code in the same session. How is that possible — isn’t each session tied to a single role at login? The answer is the SECURITY DEFINER flag for functions, which causes the …
database perl postgres
Musica Russica Launches with Piggybak
The new home page for Musica Russica.
Last week, we launched a new site for Musica Russica. The old site was running on an outdated version of Lasso and Filemaker and was approximately 15 years old. Although it was still chugging along, finding hosting support and developers for an outdated platform becomes increasingly challenging as time goes on. The new site runs on Ruby on Rails 3 with Nginx and Unicorn and uses open source Rails gems RailsAdmin, Piggybak, CanCan and Devise. RailsAdmin is a great open source Rails Admin tool that I’ve blogged about before (here, here, and here). Piggybak is End Point’s home grown light-weight ecommerce platform, also blogged about several times (here, here, and here). Below are a few more details on the site:
- The site includes Rails 3 goodness such as an elegant and thorough MVC architecture, advanced routing to encourage clean, user-friendly URLs, the ability to integrate modular elements (Piggybak, RailsAdmin) with ease, and several built-in performance options. The site also features a few other popular Rails gems such as Prawn (for printing order and packing slip PDFs), Rack-SSL-Enforcer (a nice tool for enforcing SSL pages), …
clients ecommerce piggybak rails
DevCamps: Creating new camps from a non-default Git branch
I recently set up part of a new Rails project DevCamps installation with a unique Git repo setup and discovered a trick for creating camps from a Git branch other than master. Admittedly, the circumstances that led to me discovering this trick are a bit specific to this project, but the trick itself can be useful in other situations as well.
The Git repo specified in local-config had a master branch with nothing in it but the standard “initial commit.” This relatively new project uses a simplifed git-flow workflow and as such, all its code was still in the “develop” branch.
In my case, this empty-ish master branch meant there were no tracked files in CAMP_PATH/public directory. This meant that Git did not create that directory when the repo is cloned by mkcamp
. This meant that apache2 would refuse to start. Camping without a web server makes my back hurt, so I snooped around a little bit…
I discovered two things:
- You can tell
git clone
which branch to checkout initially by passing it a ‘–branch $your_non_default_branch’ switch - The
mkcamp
command will happily pass that switch (as well as any other spicy options you include) along to …
camps git hosting