From the Dev Couch: All Ruby Baby

by Dan DeMeyere - @dandemeyere

Rubyflow is a great Ruby blog aggregator. I subscribe to their RSS feed and every day there are multiple posts that either pique my interest or are relevant to gems or technology that I work with. I don't have time to read all of them everyday so I bookmark all the good ones and set aside a couple of hours every week to parse through them all. Featured in this post are the articles that I learned something from or determined are worth saving for a later date as it could become handy in the right situation.

Realtime Data Overlays Using Google Maps

The Ghostly Map
A couple of months ago the thredUP dev team wandered over to Cloudflare's office in SOMA to celebrate their recent achievements. While we were enjoying a couple of beers, we stumbled across a 10-foot projector screen displaying a realtime geo-mashup of their service in action. My colleagues and I all looked at each other and knew instantly we had to do something similar. While our version is still on our 'fun to-do list', this post on Stac's blog is a good walkthrough about how to make a realtime maps mashup with Rails 3. They cover using Rails' cache store API, use of Backbone.js, Underscore templates, GeoKit, and the Google Maps API. Read more →

Automatic Page Loading

Endless Page Scrolling with Rails 3 and jQuery
This has to be the coolest post I came across. Do you ever wonder how Facebook only displays a certain number of comments or status updates and when you approach the bottom of the container, they automatically add more? Well, this is how you can do it. It's a relatively simple implementation using jQuery to attach a custom handler on an element that makes an AJAX call to your Rails controller to append more data to the element. The only required file is his custom jQuery library, which can be found on GitHub here.

Altering Rails' Naming Conventions

Pluralizations and Singularizations (Inflections) in Rails 3
When I first started learning Rails, I found the naming conventions difficult in routes, controllers, and models. What was plural, what was singular, and what stayed the same - i.e. if the model is history.rb, is the controller histories.rb? In general, Rails is pretty good about getting that kind of stuff right, but if you want to override how they pluralize or singularize anything, then this post will be great for you.

Optimizing MySQL

Tuning MySQL - Innodb, Buffer Pool Sizes, and Rails Stack Server Advice
I'm not going to even pretend I know 10% of what's going on in this post. Even though it's way over my head, I have to imagine every person who works on a MySQL-based app can read this post and have some valuable take-aways. Did you know you can log slow queries by changing performance values in your MySQL my.cnf file? You can even change how many seconds constitutes a long query for your app. On top of that, you can log queries that aren't using indexes. Now that's pretty slick. There is also good advice for those using a Rails/Apache/Passenger/MySQL/Memcache stack (which is what we use at thredUP). Read more →

Notable mentions

AJAX Content Pagination with Dynamic URLs

by Dan DeMeyere - @dandemeyere

Sorry about the ugly title, I couldn't think of a better way to describe the post in fewer words. The long title would have been: "How to paginate through content with AJAX and still be able to share the current content piece that is viewed without the page refreshing". See why I shortened it? Onto the post.

AJAXing content in and out creates a nice experience for the user when done correctly. You can flip through posts or articles in a magazine-like fashion. If you're having trouble visualizing this, a good example is daily.thredup.com. The Daily Thred is a new project that a colleague of mine, Heidi, and myself created over the past month. Heidi was in charge of all of the front-end (design/layout/templates etc.) and I was responsible for the back-end implementation and JavaScript. Since we're a Ruby on Rails shop here at thredUP, I chose the Refinery CMS gem to handle the majority of the functionality. As for the JavaScript library of choice, we use jQuery. I love jQuery. 

jQuery makes working with JavaScript fun. Seriously. A lot of people think of JavaScript and cringe, but I always look forward to the part of my project that involves JavaScript. Anyways...a big requirement (at least in my mind) of this project was being able to share the URL at any point in time on The Daily Thred and having that URL reference the current piece of content the user was viewing when they copied the URL. If you're reading this, you probably know that if you change the URL in the browser (i.e. thredup.com/how-it-works -> thredup.com/register) with window.location.href, the page refreshes automatically. Not very convienent for the problem we're trying to solve, but I'm sure there are security reasons for having the browser respond the way it does. The answer is not the window.location.href object in JavaScript. Close though, the answer is the window.location.hash object. Subtle yet important difference between the two.

The hash portion of the URL (http://thredup.com#hash_portion) is not visible to the controller. You can play around with the params variable in Rails all day or the $_REQUEST variable in PHP, but you'll never find the string 'hash_portion' anywhere. This is why we have to use JavaScript. I came to this conclusion after doing some brief reverse-engineering. I knew Facebook allowed you to browse pictures without the page refreshing while still being able to the share the URL of the specific photo you were viewing at all times. So I watched the URL while flipping through some photos and sure enough I saw that the URL was changing with each new picture, but only after hash portion of the URL. I figured this must be the key and I began Googling, which is a developer's best friend.

After reading a couple of posts on Stack Overflow, a developer's 2nd best friend, I quickly discovered a couple of plug-ins and libraries that already existed for this exact purpose. The only problem was they didn't seem easy to configure to our app's needs and they weren't lightweight. I wanted something fast, very fast. I also wanted the feature to fail gracefully in the event garbage was entered to the URL's hash parameter. So I decided to write my own implementation.

There are two parts to my code. The function definitions and the setup calls. As usual with most jQuery plug-ins, the setup calls need to be made when the DOM is ready. I also have an additional call that should be the first jQuery call made after the jQuery <script> includes. Here is the setup:

The paging.check_hash() call (which I'll show the code for in a second) checks the URL's hash string to see if the URL is actually referencing another piece of content. This function will intercept the current page from loading and swap out its contents for the hash string referenced content before the user ever notices. Here is the rest of the code:

As you can see the URL's hash string is updated upon a successful AJAX request. You'll also notice there's a function called refresh_social(). The purpose of this function is to find the Facebook Like and Twitter Tweet social plug-ins on the page and activate them. My controller returns a block of html to the AJAX method and therefore the JavaScript within that block will need to be called/refreshed once the DOM is visible to the new elements. Without those calls, not only would the Facebook/Twitter widgets not be unique to each content piece, they would never be clickable as the 3rd-party API calls need to be made first. 

Hopefully that was helpful in your AJAX endeavour. As always, shoot me an email (contact info below) if you have any questions or see any flaws in my code. Also, if you're looking for a new job and you're interested in learning Ruby on Rails or are already a RoR developer, send me an email and I'll forward it along to the right people because thredUP has some openings on the dev team (and it's an awesome team to work for). 

The next step for this plug-in will be adding forward/backward functionality with the hash event. Should be fun.

Dan DeMeyere
Ruby on Rails Developer & Front-end Engineer
dan@thredup.com