When I was growing up, AJAX was a floor cleaner that made women happy and feel power commercials don’t lie, or perhaps you knew AJAX as the Disney version of ACME it’s true, I swear it, though based on the timing perhaps ACME was the Warner’s version of AJAX. Perhaps Daffy and Wiley should duke it out huh?

These days, however, if you say AJAX in front of a certain group of people (they’re ok people, I swear it, hopefully I’ll be one of them some day) it means something entirely different. Today, for many people, AJAX is an acronym that means Asynchronous JavaScript and XML. Now, as always, I try to write for two types of people. Firstly, the people who already knew what AJAX was before clicking on the title of this article, and secondly, most of my current readers (relatives mostly) who though they use AJAX every day, do so without realizing what it is and how revolutionary it was.

In the beginning (of the internet), the web was new, and exciting, and tons of fun (remind me to tell you how i might have accidentally invented ebay in 1994 using usenet groups, email, and Magic:The Gathering cards, all so I could buy a bus ticket) for those of us who had access to it (thank you University of Wisconsin-Madison), but, the web lacked some things. I mean, if you remember Mosaic you remember when the web was basically all text, but then we had pictures, and graphics, and things were really cooking. However, if you go back and look at early graphically based sites from back in the day and compare them to now, you’ll notice something. Aside from the terribly ugly design, color schemes and boring layouts, you’ll notice that you have to click a link or a button to do anything and you’ll always have to leave your current page to go to the next page. That’s just how the internet was back then, but you and I both know that it isn’t like that any more, and AJAX is a big reason for that.

If you scanned the wikipedia link up above, you may have noticed the timeline and the introduction of the XMLHttpRequest object and its adoption, over time, by the majority of the major browsers. Now, from what I’ve read, this object was an innocuous little thing at first. Adopted here and there but the power of the object wasn’t really understood by many for a while. Heck, while writing this article, I discovered that AJAX as a thing is barely 10 years old, but I guess when something is so revolutionary, and, honestly, so obvious that I’m sure developers all over would have been going Why didn’t I think of that?, ubiquity doesn’t really take that long. (I have no idea if I just used the word ubiquity properly, I really hope I did, cause I’m one of those people who gets annoyed when people use modifiers on unique - which was a no no when I learned about such things.)

So, the advent of AJAX was probably the beginning of what many people also call Web 2.0. Web 2.0 as I see it, is also the advent of the User Interface (UI) and User Experience (UX cause UE sounds weird I guess) being important. This simple little object allowed so many sites to do so many things, but in reality, by itself, as I understand it, the object only really does one thing, but it’s a pretty powerful thing.

Remember, 3 paragraphs ago, when we talked about links and buttons always ‘taking you’ somewhere else on a web site? If you filled out a form, but missed something, you had to wait for the page to process your information and then tell you what you did wrong. (Ok, depending on your age and web experience, maybe you didn’t have to do that). Today however, when you’re filling out a form, you’re told, sometimes immediately, if the information you are entering is already in their database of the website. That’s AJAX and that little XMLHttpRequest. (If you are filling out a form and you are told something you entered doesn’t fit the desired format, length, etc…that’s not really AJAX per se, that’s just JavaScript alone). When you are shopping on a web site, no longer do you have to wait for a new page when you add (or delete) something to your shopping cart. On many sites it happens automatically. That’s AJAX. (Though, Amazon does not use AJAX for cart additions, and I’m not sure why because they use AJAX in a lot of other places).

Simply put, to my intermediate beginner understanding, the advent of AJAX showed developers that with that little XMLHttpRequest object, they could send information to the server, return it, and update the page you are currently on, without you seeing anything happen except exactly where it was supposed to. This works because of the power of JavaScript (and is made simpler by powerful JavaScript libraries, like jQuery which, like Rails does, automates a lot of your basic JavaScript in built-in methods while allowing you to seamlessly integrate your own JavaScript code if need be) and the asynchronous (see what they did there) power of the XMLHttpRequest object.

I won’t get any more in-depth about the nuts and bolts of this, but to say, that it’s one of those front-end things that always would cause me great agita and while I’ve made attempts at learning to work with it in a variety of arenas, those attempts never really stuck, but I have decided the time was now. I really had to learn how to use AJAX because people care about the UI//UX these days (sometimes more than the functionality, which doesn’t make sense to me ) and if you want to be taken seriously as a developer you have to use AJAX, and so I set about learning how, and as always, Ruby on Rails makes it an easier task.

I had read a bit about using AJAX in Ruby on Rails before but never really had anything to try it on, but finally I had happened upon the right mental circumstance and project circumstance that would allow me to, hopefully, integrate my first use of AJAX into a Ruby on Rails application without being too ambitious about the end result, so that the likelihood of being overwhelmed would be slight.

Introducing the Whole Foods Application

I currently am employed at a natural food manufacturer whose products are carried in Whole Foods. As such when you are a Whole Foods vendor, you have access to sales data across the (at this point) well over 400 Whole Foods stores world wide. (Did you know there were Whole Foods in Canada and England?) My company has had access to this data for a while now. (I don’t have any old reports in front of me to look but it’s probably been more than 5 years) through their vendor portal with a company called microstrategy.

Now, as I may (or may not, I’m not sure) have mentioned long ago when I told you all my story to date, my first serious foray into any kind of computer geekness was through databases, a variety of them. While I had was fluent in a few of them at the time, our company was (and still is at this time) running an ERP that used a SQL Server 2003 back end. In an attempt to be a more productive employee and provide more useful data, I had enrolled in a few courses at a local community college that had taught me not only the basics of database design theory, but the specifics of working with SQL Server 2003 (and MySQL was another course but not relevant to this article).

So, when I started looking at this microstrategy portal, I thought, that it could be really useful, but I also thought that all the built in reporting it provided was, well, kind of not that useful, so being a geek, who liked databases, and data normalization, I did what any one with my brain would do, I decided i was going to build my own project that would store this data and allow me to peruse and present it any way that I could. At that time, the only thing I was even comfortably fluent in was database design and the applications mentioned above, and since it was readily accessible, and work related, I decided I would build a SQL Server 2003 database that would allow me to present better reporting. (Side note, at one point I did independent work for another company and built a MySQL version at home, but that didn’t last long)

I won’t bore you with the nitty-gritty of the database design, but suffice to say, I was able to design a database that allowed me to download the weekly sales data (as granular as I thought I needed to deal with) after every fiscal period, and import it into my database an provide reporting to the sales team to work on. Every 28 days (because whole foods reporting is by ‘fiscal weeks’ and their fiscal year starts on October 1, so that’s weird, right?) I would log into the whole foods portal, download the most recent data, and use the SQL Server import tool to add the data to the database.

Certain things, new stores opening, stores closing, changing names, they all had to be dealt with manually. I had to run a variety of queries each month to make sure the data imported properly, however it worked pretty well and turned into routine (in fact there was a company, independent of me, that sold the idea to companies with cooler data interfaces and graphs and such, but what happened next I believe caused them a problem or they were just purchased by SPINS and shut down - I don’t know)

A recent change to the service gave control of the reporting to Whole Foods directly. This led to a TOS change (which barred automatic downloading which I think doomed the company above) and added my first experience with anything than your standard ‘logging in’ verification. In what I consider a somewhat ridiculous level of security, I had to download an app to my smartphone and every time i want to log into the Whole Foods portal now, I have to have my smart phone, open the app and let it ‘scan’ the QR code on the screen to make sure I’m valid. It’s an app called Usher, and I’m sure if you’ve had to use it, you know what I’m talking about. I hope no one out there needs to use it for more than one service.

Anyway, even with the added complication, the basic process of doing the ‘monthly’ reporting for Whole Foods stayed the same internally. However, I was still getting busier, and I noticed that I could now get data broken down not only by the week but daily. Perhaps this was always available and I didn’t notice, or perhaps this was a new addition when Whole Foods took over. That seemed like a great thing to me, for a variety of reasons that aren’t important, but integrating that would mean basically starting my database over from scratch.

“But John”, you’re wondering, “why don’t you take advantage of this opportunity and your desire to be a web developer and build a web application instead that will do a lot of the processing for you, while also making reporting available on demand when any of the staff want to see it as opposed to you having to create it yourself every 28 days?”. Well, whoever you are reading this, that’s a pretty good question, and I realize an obvious one, and I do have an answer, but not a good one.

The short version is I didn’t want to. The slightly longer version is that while I had been working on learning web development for a while, I had purposely avoided taking on any projects that would be related to my job, for a variety of reasons, but the more I struggled for what I thought were ‘good’ project ideas, the more it became apparent that working with ‘what I knew’ would probably make it easier, so I decided that I would not only take advantage of the daily sales numbers, but I would use this as an opportunity to take my skills to build a project that I’m familiar with that also provides an opportunity to learn a variety of new skills (AJAX is kind of common to a lot of things, but file uploading and processing isn’t as common and that is needed in this as well).

So, I got started on the Whole Foods application. I created the basic Model stores, tested them, worked with the validations, started building out the basic CRUD functionality (with my own adjustments) and decided that not only was it time to try and use AJAX but I had the perfect opportunity right here. I could take advantage of the fact that stores sometimes close and have store closure be an AJAX interaction instead of a basic interaction, so off I went.

Integrating AJAX into Rails, if you’re testing, isn’t as easy as it looks.

As you can tell from the heading above, this isn’t going to be a quick - oh look I did some studying and it just worked. Per usual, there were some hiccups, complications and down right frustrations that almost got to me, but in the end, thankfully, they didn’t.

So, the first thing I did is look stuff up. A little bit of advance research never hurt anyone. On a return business flight from a quick trip to Oakland (that also involved spilled water and me killing my laptop temporarily), I pulled out The Rails Way which is a great Rails reference, and has a chapter on AJAX. I had so studiously avoided the topic before that I knew pretty much nothing about it. It turns out, in theory, adding AJAX to a Rails application is pretty easy; when you’re creating your link you add the following code remote: true. Rails does a lot of the work under the hood to make the work AJAXy. Of course, that doesn’t make the functionality work, you gotta do a bit more than that, so off I went.

I found great videos on gorails and an older, but helpful, video on Railscasts, I felt ready to get started.

Stores open, stores close, and when stores closed, it should be indicated that they are closed so that you don’t try and go there any more or look at their data any more. Thus, if you have an application with open stores, you need to have a way to close them, and that’s where I wanted to implement AJAX at first. I wanted a Close store link that would cause the store to be marked as closed in the database but not leave the page. I also wanted the page to change some content to show that the store was closed. I could have just easily written the code to this and assumed it would work, but that’s not how it’s supposed to be done. It’s supposed to be tested, so I did a little research on how to implement javascript testing using RSpec and Capybara. Rails 4 in Action has some information on using javascript to upload multiple files, and it guides you on how to set up javascript testing. Turns out telling RSpec that a test is a javascript test is just as easy as it is to create the link. Just put js: true in your scenario declaration and you’re good to go.

Sort of.

Testing with javascript is done differently than non javascript testing. In short, the testing literally opens a browser window and performs the action on the screen. Seriously, you can watch it happen. Turns out this requires a gem - selenium-webdriver - to do that. Ok, no big deal, that’s a quick install and we’re ready to go.

Except, we’re not.

By default, the selenium-webdriver gem is going to try and use Firefox. Like many of you (probably) i studiously update Firefox when they tell me to. However, a recent update (around August of 2016, depending on when you are reading this) altered something called the ‘geckodriver’ and it isn’t compatible with selenium - except for a (currently) beta of version 3. I tried all sorts of ways to get that to work, to no avail, and to much frustration. I was reaching that point where I was ready to give up, I just couldn’t get there.

Finally, somehow I happened upon this SO post which seemed to be the solution to my problems. Following the instructions, I set up my testing environment to use Google Chrome (which I had to download since I don’t use it at all) instead of Firefox, so now my tests will pass without a problem, right?

Wrong

So now the browser was launching at least, but the test data wasn’t being found by the test. Rails in 4 Action had this covered. Javascript testing works slightly differently so you have to alter the way your testing processes your databases. Their tutorial guides you in setting up the DatabaseCleaner gem (yay I already knew this one from my nba testing, but, as with the referenced article, I had some issues to work through. Primarily, seed data.

Whole Foods stores are split into regions, every store belongs to a region. Reporting by region is vital. So, all stores have a region_id. My testing loads the region names into the proper database as a way to have some useful information into it. The Database Cleaner gem requires some tweaking when working with seed data. The setup for your Database Cleaner gem when you’re working with seed data (and not using javascript in your testing) isn’t terrible. For reference from my NBA information, it looks like this:

``` config.before :suite do DatabaseCleaner.strategy = :truncation, {:except => %w[teams divisions]} end

config.before :each do DatabaseCleaner.start end

config.after :each do DatabaseCleaner.clean end ```

So, i was stuck again, I tried a variety of things, read some blog articles that in my frustration I didn’t mark and can’t find in my history, even the one that worked it out, but that article I came upon pointed me in the right direction, as you can set up your Database Cleaner even more precisely on how it handles tests, javascript or not, with seed data. After a bit of trial and error, I happened upon this configuration:

``` config.before(:each) do DatabaseCleaner.strategy = :transaction end

config.before(:each, js: true) do DatabaseCleaner.strategy = :truncation, {:except => %w[regions]} end

config.before(:each) do DatabaseCleaner.start end

config.after(:each) do DatabaseCleaner.clean end ```

I know it looks almost exactly the same, but with the seed data, I can’t apply to the suite, and I only need trunctation (transaction is the default) for the js stuff right now.

So that was it, the test passed. Wait, I didn’t write any of the test code or indicate what I was testing clearly, well, that’s kind of the point. The test part was easy, and is becoming rote, it was the implementation of AJAX and dealing with the unexpected barriers that should not exist again and again that are the point. Again and again, roadblocks that shouldn’t have been there showed up, and though it took me days to find the solutions, I did finally persevere, and I didn’t give up, which, if you’ve been around here long, you know could have happened. And a frustration like this, something that should be easy to work that I just couldn’t get to work (though I did after a while) is the kind of thing that would trigger me in the past, but no longer does.

So, perhaps that’s the moral of this one then folks, don’t give up if you really wanna do it. If it gets real bad, take a break (I took a couple days off from this before going back to it and getting it fixed), so you can come back fresh, but there’s usually an answer, and no matter how many times you fail you only have to find the answer once.