Dear Experienced Ruby Dev, Come Join Our Team

by Dan DeMeyere - @dandemeyere

First thing's first, I'm not a recruiter. You won't see the following terms in this post: 'hacker', 'rock-star', 'pirate', 'guru', or 'ninja'. I'm not trying to get referral money for getting someone hired. I have no ulterior motives other than trying to find someone who has solid Ruby experience that can join our team, tell us what we're doing wrong, teach us to write code that can scale, and be a part of a team that we have worked hard to build.

Now that the disclosure is out of the way, let me introduce myself. My name is Dan DeMeyere and I'm a developer at thredUP. We have 3 development teams: web, ops, and mobile with 4, 3, and 2 developers on each team respectively. I'm currently the lead for the web team and while I have a solid and practical understanding of Ruby (our website is a Rails app), I'm no expert. I want to learn and so does the rest of the team. Some people say they want to learn, but we mean it. We do 'lunch & learns' on a regular basis to teach each other about new technologies we come across, interesting solutions we implemented, and new libraries/classes we've written, but we're still lacking that go-to Ruby developer who can push us to the next level technically.

While this post might seem like a plea, it's not written out of desperation - we just care a lot about our team and what we're trying to accomplish. We're not slouches, either. Our team is hard-working and highly productive. We roll out features every week and we make sure not to accrue technical debt along the way. We have RSpec and Cucumber test suites and a CI server to run them.

Our Technology Stack

While we're not locked into anything in particular, here is what we're currently working with:

  • Rails 3.1 (soon to be upgraded to 3.2 on Ruby 1.9.3)
  • HAML/SASS/CoffeeScript for our views
  • MySQL (and a couple MongoDB/Mongoid models)
  • EC2, RDS, and S3 for our server and hosting needs
  • Capistrano for deployment
  • GitHub for repository management
  • Asana for project management

If you're curious what else we use and work with, I'm happy to expand via email.

Working at thredUP

Working at thredUP is great. My favorite question to answer when I'm interviewing someone is 'why do you like working at thredUP?'. I have a field day with that question because I genuinely love working at thredUP. thredUP is a meritocracy. Your contributions to the team and company trump everything. Better yet, upper management cares and they pay attention to everyone. If you're putting in extra work, it will not be lost on them. They're also transparent and accessible. Our CEO shows us the same presentation he shows our board every month. He'll tell you how much money we have in the bank, what our burn rate is, what he's excited about, what he's worried about. There are no closed doors at thredUP, we're all in this together.

Also, thredUP has some great job perks:

  • Work From Home Wednesdays
  • Catered lunches twice a week (plus fully-stocked fridge/pantry)
  • No vacation day limit
  • Big ass Apple LED Cinema display and a computer of your choosing
  • Office at 2nd & Market in downtown San Francisco right next to the BART
  • Competitive compensation

I could go on about why working at thredUP is awesome, but what it comes down to is that you would be joining a close-knit, no-ego dev team that is always looking out for one another. We all tackle bugs and help with Customer Service if a user is experiencing a technical glitch. If something breaks, we don't point fingers at the person who coded it. If you write a piece of the app that experiences a lot of bugs, you're not going to be pigeon-holed into fixing them. No one is stuck 'owning' any piece of the app - we spread the knowledge so the team stays flexible. There are no rogue devs on the team - everyone contributes in a coordinated effort.

We have fun too. Other than the standard company-wide happy hours, we've been known to throw Halo gaming parties, have Scotch-drinking Settler's of Catan nights, and do things like Casino Night. You'll also hear a lot of Arrested Development and Super Trooper quotes being thrown around mixed-in with a cavalcade of sarcasm. Lastly, and what the development team holds very close to our hearts, you'll be exposed to our treasure trove of awesome Gifs that we post during the day in our Campfire chat room.

I'm not listing any ridiculous job requirements that you see in job postings. If you're genuinely interested, have the Ruby experience we need, and are able to work in SF, please email me - dan@thredup.com.

Upgrading Rails from 3.0 to 3.1: What the Guides Don't Tell You

by Dan DeMeyere - @dandemeyere

We upgraded the thredUP app from Rails 3.0 to Rails 3.1 this past week. On the day we deployed the upgrade, our test suite was green and everything looked solid locally and on our staging server, but out of sheer paranoia I decided to take one of our front-end servers off of the load balancer and deploy to it so I could poke around on the Rails production environment....and then a bit of chaos ensued.

There are some aspects of a production environment that can't be replicated in your test suite and can't be invoked locally. A good example of this is SSL. Did you know that `ssl_required` was deprecated in Rails 3.1? I didn't (here's the solution btw). Then there are production-only gems to worry about (ex: monitoring services). New Relic's gem required a bump for Rails 3.1. And by required a bump, I mean the gem caused the entire app to crash with a cryptic error message. Fun!

You're probably thinking that this upgrade lacked preparation. Quite the contrary. Before I started the upgrade, I read guide after guide about upgrading to Rails 3.1. Because we wanted to upgrade in phases, I wasn't interested in the asset pipeline requirements, but it seemed as though that was the only thing every guide was focusing on. What the guides weren't focusing on were all the gems that would have to bumped (and their dependencies) and what the ramifications of those bumps would be. ActiveRecord, Cucumber, and PayPalNVP were a couple gems in particular that had noticeable changes that deserved some love in the upgrade guides. So that's what this post is, some love for the not-so-obvious deprecations that should give you clearer expectations of what you'll be running into when upgrading to Rails 3.1.

Active Record

Condition hash syntax is on it's way out. It's been fully deprecated from named scopes and the `find()` method.

Another big gotcha is 'include_root_in_json' being defaulted to false for every model now. Here's the difference:

Small difference between the two, but if all your JSON responses previously had the root included and you have external apps (iPhone, Android, etc.) relying on your app's internal RESTful API (like we do), then it's a significant difference as it's possible all those API endpoints will have to changed or the apps will break. So how to change this? Below I'll demonstrate how to set an app-wide default and then how to override the setting in individual models.

Gem Bumps

Almost every Rails app relies on a myriad of gems. Including our development and test environments, thredUP uses over 50 external gems and a handful of our own private gems we've created over time. When we upgraded from Rails 3.0 to Rails 3.1, there were some notable gems that required version bumps.

There are some big boys in there (ex: mysql2 is our MySQL adapter). If you use any of the above in your app, which I'm betting you do, make sure to take note of their version bumps

PayPalNVP

If you use the PayPal NVP gem, expect to make some changes. The biggest for us was that the PayPal NVP API requires all authentication upon object instantiation. Example:

If you do full 3rd-party API mocking in your test coverage, you could see how this change would be problematic.

Lastly, make sure to read the Rails 3.1 release notes or Ryan Bate's gist of 3.1 RC4 changes. That's where some of the standard Rails-only deprecations will be. The biggest one to note - all forms (or any Rails view helper that results in HTML being outputted into the source) requires a `=` instead of `-`. It's a simple change, but if you use a hyphen on accident, nothing is outputted to source and it can be quite confusing to debug since no errors will occur and nothing is in the HTML.

If you came across any unique errors when you upgraded your app to Rails 3.1, please mention them below in the comments and I'll update the post afterwards to include them.

New Additions for your Rails Toolbox

by Dan DeMeyere - @dandemeyere

One of the biggest advantages to using Ruby on Rails as your web framework is the open source community. They unselfishly release new gems every day. They build the best tutorials for free and they commit to the latest Rails builds on a daily basis. The only variable left in the equation when you're building a Rails app is knowing what tools to use when approaching a project implementation. Having a solid toolbox at your disposal is essential to furthering your professional development as it allows you to take on more challenging projects that are outside your comfort zone.

When I first started developing with Rails, I was blown away by my CTO's ability to nonchalantly take on challenging projects. The project or feature would seem outlandish and at times borderline impossible, but he would say something like "we'll figure something out" and somehow he always did. It seemed like magic. After watching closely for many months, I came to realize he had three things: a positive outlook, a solid toolbox, and a creative imagination. The combination of the three were a potent arsenal for tackling epic projects. He wouldn't think about why it couldn't be done - he would start in the ideal world that everything's possible and begin brainstorming from there.

Having a good outlook and creative imagination is not something you can attain from reading a blog post, but you can always add more tools to that handy toolbox. Here are four new additions to my toolbox; hopefully one of these will help you one day when you come across a new project.

Storing your ActiveRecord Objects in Redis

Link to article →

Speed is important. Rails contains a fair amount of overhead and it's considered one of the harder frameworks to scale. It isn't an issue when you're website is small, but as you grow you'll discover some of the earlier code that was written in your app won't hold up as the user base grows. This results in feature re-writes and becoming more clever with your implementation. One of the first tools to reach for when attempting to speed something up (outside of profiling your DB queries) is cacheing. We use memcached at thredUP, but the problem with memcache is that the data isn't persistent. If your memcache server goes down, you can lose all the cached data within it. This makes memcache only feasible for information that can afford to be lost. What about data that needs to be written to the DB? You can't reliably do it with memcache, but you can with Redis.

The tool I linked to above is a gem that the fine folks of Gowalla, recently acquired by Facebook, wrote to accommodate quick writes and reads of an ActiveRecord object. Their example is 'liking' something. You have to be able to like something quickly and pull back information on that like such as how many others have liked it and who they are. Personally I've been wanting to re-write thredUP's in-house notification system for a while as it hits the database on every logged-in page load and this is going to be the first tool I reach for when that time comes.

Converting Dates Between Ruby and JavaScript

Link to article →

This one is very straightforward. In multiple parts of our app, specifically areas of the app we're doing background AJAX polling, our JavaScript scrapes time data off the DOM (like timestamps of objects stored on an attribute of a div). The problem is that JavaScript's time (local) and our server's time (GMT) are in different time zones. The link I listed above will give you a quick and easy way to go back and forth from Ruby's time class to JavaScript time class.

Lazy Evaluation and Method Chaining

Link to article →

Most people know about method chaining in Ruby, especially within the context of ActiveRecord methods. Most people also know that an ActiveRecord call does not hit the database while it's still an ActiveRecord::Relation object, which is an example of lazy evaluation. The real tool comes from using both of these together.

The best example I can give is compound filtering. If you go to an e-commerce website and select 'Sort By: Lowest Price' and 'Gender -> Men', those are options that will compound to filter your results. One way of implementing this is having a nasty 'if params[:sort] = "Lowest Price" && params[:gender] = "Gender"' block for every possible filtering scenario. That is obviously not ideal. But if you were to add some named_scopes that build conditions for each individual filter and method chain all the compounding filters onto a ActiveRecord::Relation object that executes its call to the DB at the end, then that would be a clean way of doing it.

ActiveRecord Key Value Stores

Link to article →

Key value stores are awesome. They're super simple and super fast. To get geeky for a second, searching with key value stores in big O notation have a time of O(1) (that's the fastest). I like to hack together Hash look-up objects in Ruby all the time to speed up checking whether a ActiveRecord ID is in a collection. The alternative is using an array (assuming it can't be looked up in the DB) and even if the array is sorted and the array look-up call is using a simple B-tree algorithm, the notation is still O(log n). You just can't beat key value stores for look-ups.

The link I referenced is leveraging the method_missing method of a class as a way to arbitrarily set key values. I would never use something like this on a heavily used model such as User as using method_missing like that is dangerous, but it does make sense in context of ApplicationSettings. Either way, it's a clever implementation for dynamically setting class attributes and it opens up your imagination for ways in which it can be used.

Have a tool you would like to share? I'd love to hear about it below in the comments.

Rails Association Tips

by Dan DeMeyere - @dandemeyere

Rails is one of those languages where you can infer how it should interpret code. A more simple way to word that is this: sometimes you'll be coding something for the hundredth time and all of a sudden you'll think to yourself 'I wonder if this will work' and you'll try to change a convention based on your previous experiences with that language. This recently happened to me and I wanted to share what I discovered.

We have a lot of named scopes in our app. Typically our named scopes look something like this:

In that example, our User model has_one :concierge_information (btw, definitely check out our new thredUP Concierge app). While I was creating this scope, I wondered if I could infer which 'joined_via' column I was referencing since I was querying over two tables. So I tried this:

And it worked! Much prettier, right? That example doesn't save a lot of keystrokes, but it should help keep things organized if you're joining across multiple tables and/or querying a lot of ambiguous columns (when you're query references a column name that exists on multiple models you're querying across). While I was writing this, I thought it might be nice to share some other association-related tips I've learned.

ActiveRecord Association Tips

Rails associations are awesome and they come with a lot of built-in class methods/helpers. The basic rule of thumb that I use is that if you're accessing an object's association, you probably have access to the ActiveRecord methods the association's model has. For example:

In that example, you can do any ActiveRecord query on that user's orders as if you were querying a subset of the Order table itself. This can be very handy if you have nested associations.

Object Association Tips

One that I recently came across was the built-in method for creating an associated record that is a has_one association. It ended up just being 'create_#{association name}'. It's not life changing, but it's nice to know. Here it is in action:

In case you're wondering what the has_many version looks like:

This brings up an important note about something I was fuzzy about until recently. When are these objects saved? Obviously a .create() call will write to the DB, but what about when you create/build the object outside of the association and then assign it afterwords? Here are some examples (these are all under the pretense that @user is already stored in the database):

That was helpful for me to learn as unnecessary .save calls result in additional calls to the database.

Lastly, I came across an edge case scenario that I was curious about. If you're using the '<<' operator to associate newly created objects, how do you know if the object you're creating failed? The answer is you don't. However, you can use the .push() method and it will do the same thing as the '<<' operator except that it will return true or false depending on whether the creation was successful or not.

Improving Your TextMate Proficiency

TextMate is great, but on more than one occasion I've come very close from going 'Office Space' on my computer when TextMate thought it would be fun to beach ball and stop responding. Over time, much thanks to my CTO, I've found some ways to make my TextMate experience faster.

PeepOpen

Pressing (Command + T) in TextMate brings up the 'Go To File' window. The suckiness of this feature is two fold. First, if you have a large project (thredUP has over 2,300 files in our project) the 'Go To File' window will hang frozen for about a year. Second, if you have multiple files similarly named then it's practically useless. Enter PeepOpen ($12).

PeepOpen is awesome for a number of reasons. For one, PeepOpen keeps a persistent index of your project files so lookup is incredibly fast. Also, through some sort of magic, you are no longer limited to just typing file names to find a file. If I were looking to load the './app/controllers/admin/users_controller.rb' file, I could type 'admin users' and the results would be dramatically narrowed. You can type any part of the path and it will match against the index.

Also try: (Command + Shift + T) brings up a window to find a method within a file. Especially handy in large models.

Project Searching

If you're searching within a file, TextMate's built-in (Command + F) is fine. If you want to search multiple files such as a folder or the entire project, don't bother pressing (Shift + Command + F). It will take forever to find anything. Luckily there are multiple free and easy to install alternatives.

The first alternative is AckMate. I think it's the most widely used search plug-in. I didn't like it. First off, it doesn't support .haml files out of the gate. So I use a much less known plug-in called NiceFind. It's simple to install (double-click the NiceFind.tmplugin file after download) and it's very fast. It also allows you to select a directory in TextMate and press (Command + Shift + T) to only recursively search in that directory.

If I'm doing a costly search such as searching through some logs, I always default to the good 'ole grep command. However, sometimes you're on the command line and outside of TextMate and you want to search for files regardless of where they are stored in your app. If that's the case, then project_search is going to be your buddy. For example, I could do 'script/find helper "def emit_"' and it knows to only search helper files for that method.

Snippets

My favorite part of TextMate. If you aren't aware of TextMate Snippets, open TextMate and go to Bundles -> Bundle Editor -> Show Bundle Editor and explore all your different options. They are broken up by file detection, which I believe is done by your bundles. So your models might be under 'Ruby' or 'Ruby on Rails' and your views might be under 'Ruby Haml' if you have a separate bundle for HAML. I could list some good ones, but this cheat sheet is all you really need.

You can also go one step further and create your own snippets. While you're in the Bundle editor, select the bundle you want to add a snippet for and then click the '+' button in the bottom left. One of the ones I made is for Haml. Very commonly there is a JavaScript file I want to include for a page that also requires a jQuery DOM Ready setup call. So I created this snippet:

For the Activation field, I selected 'Key Equivalent' and put in the three letters 'cfj'. What this means is if I'm in a Haml file and I type cfj and press the tab key (which is usually how most snippets are activated), the following code is output for me:

The $1 variable set in the snippet is a way to autocomplete portions of the text. So after you press tab, the cursor will be waiting in the open quotes on the JavaScript include tag. Whatever I type there will also go before the .setup(); function call as well.

ReMate

Lastly, if you have a really large project, ReMate (free) is a must. Have you ever selected TextMate and it just hangs there? It's probably because TextMate is refreshing the entire project tree. If you install ReMate, you can disable this feature. After you install ReMate, go to Window -> Disable Refresh on Regaining Focus. That simple. You can toggle this option if you want this on or not and if you want to manually refresh your project tree, right click in the folder pane and select 'Refresh All Projects'.

If you know of good ways to speed up (maybe speedUP?) your TextMate usage, I'd love to hear about them in the comments below.

Overriding the Default Retrieval Limit in FbGraph

by Dan DeMeyere - @dandemeyere

One of the many thredUP projects I'm fond of is the Daily Thred. Every weekday, two of the Moms here at thredUP post a new article that is discussed in the chat tray on the right side of the page. This chat tray was built from scratch utilizing the Facebook Graph API and FQL with JavaScript.

One of the many challenges that surfaced was collecting metrics on activity occurring in the chat tray, since all the activity was stored in the Facebook databases. I didn't want to pull these metrics with JavaScript and since our server language of choice is Ruby, I turned to FbGraph, which is a full-stack Ruby Facebook Graph API wrapper.

It's a cinch to install and the usage is intuitive - I couldn't have been happier with the gem. After I finished implementing the metrics for the chat tray, I deployed to production and quickly found a problem. The way our chat tray works is as follows: every article is tied to a Facebook Post object. All comments made in the chat tray are Facebook Comment objects where the parent_id is the Post's id. Simple enough. So to fetch all the comments for a post to analyze the results for the metrics, I did the following with FbGraph:

The problem was the number of comments returned maxed out at 50. Since some of our chat tray conversations have over 300 comments, it was crucial I had access to every comment. I tried some standard ActiveRecord conventions like post.comments.limit(1000) to no avail. After a round of Google searches and sifting through some Github issues, I came across someone who had a similar concern. Their solution involved paging through the comments. This wasn't sufficient for me so I went poking around in the gem.

After a quick cd `bundle show fb_graph` command, I started to peruse around the gem's lib files. Inside the Post class, I noticed the associated @_comments_ object was created through the Collection class. Once inside the Collection class (/lib/fb_graph/collection.rb), I noticed there were four variables that def fetch_params checked for - one of which was 'limit'. So after adjusting my script like below, all was good.

Getting Started with CoffeeScript (Part 1 of 2)

by Dan DeMeyere - @dandemeyere

If you're a Rails developer, CoffeeScript is something you need to pay attention to. With the news that CoffeeScript will be included by default in Rails 3.1, CoffeeScript is definitely generating a sizable amount of momentum and the core Rails team believes it's the future. Knowing this, I was looking for an opportunity to use it and a clean project presented itself this sprint at thredUP. So with the help of my colleagues Kylie and Chris, we dove in and started playing away.

The first step is installing CoffeeScript. I used CoffeeScript's official installation instructions, but I ran into some weird export PATH environment issues so I installed it with Homebrew instead.

To install Homebrew, just run this command in your terminal (assuming you have xCode installed already):

Next, you need to install Node.js, which will compile your CoffeeScript for you. With Homebrew installed, all it takes is one line:

You're almost there. Just two more install commands left. The first is installing Node Package Manager and the second is using NPM to install CoffeeScript.

Done! Pretty harmless, heh? Time to start writing some CoffeeScript! Since people abbreviate JavaScript as JS and I'm a sucker for typing less, I'll just refer to CoffeeScript as CS throughout the rest of this post. It doesn't matter where you place your CS files, but I believe Chris told me the best convention is in your app/assets folder. So if you haven't done that, go into your terminal and make the directory:

You can end your CS files with .coffee or .js.coffee, so create a new file in there so we can finally write some code. The project I'll be using as my example is heavily focused with DOM manipulation and since thredUP's library of choice for that is jQuery, you'll be seeing a lot of that in here.

When I first got everything setup, I was a little bit paralyzed. I didn't know where to even start. So the first thing I did was I wrote what I wanted in code in plain JS:

It's basically a setup function that calls another function which iterates over an array and logs the contents. What does this look like in CS? Like this:

Pretty sexy, right? CoffeeScript is very clean (based on Ruby and Python syntax) and it makes it much easier to work with, to read, and it's easier on the eyes. Before I get ahead of myself, there's a couple of things in this code that need to be explained, but first let's give you some resources. Syntax reference for CS can be found here. Once you're on that website, click 'Try CoffeeScript' and an interactive window appears which allows you to type CS directly into a console that the website compiles the corresponding JS right in front of you. This is what it looks like when I typed in the code above on their console:

The first thing you're going to notice is the JS code that I original wrote and attempted to create is different from what was outputted on their console. The reason is because CoffeeScript's compiler is a better JavaScript programmer than me :) I can assure you that my original block of JS code and the compiled CoffeeScript JS code execute the same, but the CS version is going to do it a lot smarter and probably more efficient. CS is going to compile into the best JS it can without changing how your JS functions.

Another note worth mentioning is that the marketDemand object is oriented off of the JavaScript 'window' object. I didn't know this, but apparently this is something I should have always been doing as it prevents objects, variables, and functions that you write from spaghetti scoping out of control. I think it's one of those "trust me, it's better practice this way and you don't want to discover first-hand why it's necessary, but it is" things.

So let's paste that code into the .coffee file you created. The next step is to compile it on your terminal:

If you paste that into your terminal, it will compile all CS files in your app/assets/coffeescripts folder (-c stands for compile) and output them into your public/javascripts/coffeescripts/ folder (-o stands for output). Now, if you're always looking for short-cuts like I am, you'll like this next one:

That command will watch a specific CS file and when it detects a change, it will automatically re-compile it for you. Pretty killer, right?

This post became a lot longer than I originally intended so I broke it into two posts and I'll post the second one in a couple of days. In the next post I'll be going through using jQuery in CoffeeScript and covering if/else statements and other standard snippets of JS -> CS that you might find handy.

How to Develop Locally with the Facebook API

by Dan DeMeyere - @dandemeyere

When you create a Facebook application, they require you to give them the domain of your website that will be accessing the Facebook API. The Facebook app keys they supply you with are only valid through the domain of the URL you listed. This strikes the following question: how do you develop locally if your development domain is something like 0.0.0.0:3000 or yourapp.local? The answer is SSH remote tunneling. You use a service to connect a port on your local machine to an open port on a public server somewhere (preferably securely). I've been using tunnlr.com to do this. Tunnlr is not the flashiest service, but it works really well. The following tutorial was made based on my experience with a Rails app, thredUP.com, that I develop for. I'm not sure how useful this tutorial will be to you if you're using a different framework.

Tunnlr Account

Once you sign-up for an account at Tunnlr, you will be given your Tunnlr URL. It will look something like http://web1.tunnlr.com:11908. Write this URL down, you'll be using it later. While you're on your Tunnlr account page, you'll find a section towards the bottom that says 'Need help?'. Follow the steps listed under 'How do I use Tunnlr with Rails' including the plugin and two gems along with created the tunnlr.yml file. I'm not positive you need to do this for creating manual tunnels, but I did just in case. The remote port variable is the number at the end of your tunnlr URL. For example, if your URL is web1.tunnlr.com:11908, your remote port would be 11908. Tunnlr says to use port 3000 for you local port, but I've been using 80 because of some issues I ran into with our app.

After everything is configured, it's time to get this baby up and running. I've always deferred to creating a manual tunnel as opposed to doing any rake tasks, but to each their own. The command to do so is in the 'How do I manually start a tunnel?' help section. It should look something like this:

In this example, 11908 is your remote port number and 2202 is your user number, which you can find on your Tunnlr account page. If you plan on tunneling a lot, I suggest creating a bash alias like this:

Now I can just type 'tunnelme' into my terminal any time I want to test Facebook locally. So assuming you're ports are ok and your local development server is running, you should be able to go to your Tunnlr URL (i.e. http://web1.tunnlr.com:11908) and view your local app. If this doesn't work and you have good reason to believe it has nothing to do with your local development, try adding the facebooker.yml file that is detailed in the 'How do I use Tunnlr with Facebooker?' help section.

Facebook Setup

Assuming your tunnel is good, now you're going to need to setup a second Facebook application to develop locally. Go to Facebook developers page and create a new application. When they ask you for your Site URL, paste your full Tunnlr address (http://web1.tunnlr.com:11908). For the Site Doamin, just put web1.tunnlr.com. Boom, you're done. Enjoy :)

Parting Gift

Most Rails apps have different config files for each environment such as development, test, and/or production. This is really convenient in the context of developing for Facebook applications as this is great way to handle having different App ID, API Key, and App Secret variables. Definitely setup your Facebook app in a way that is indifferent of what environment it's running on.

If you have any questions about setting this up or I messed up somewhere along the way, leave a comment below and I'll follow up the best I can.

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

From the Dev Couch: Node.js, Facebook Open Graph, & Mutant Labs

by Dan DeMeyere - @dandemeyere

Like many others, I come across a lot of great articles and websites every week. The problem is I don't have time to give each one their fair due so I end up bookmarking them for a later read. I'd rather set aside a block of time to read each one thoroughly then skim and move on because I'm always paranoid I'll glance over something profound. Since I took the weekend off, I've been able to plow through about 30-40 of the articles in my backlog and I thought I would share a curated list of ones I think are worth your time. I've broken them out into different categories so people can skip to the topics that interest them the most.

Learning About New and Old Technology

Topic: Node.js
Link: mashable.com/2011/03/10/node-js

It seems like every week there is a new JavaScript framework coming out that will supposedly change the JavaScript landscape forever. After reading this article, Node.js might actually be that framework - but in a completely different way that I anticipated. Node is nothing like jQuery or Backbone. Node is not a client-side framework. Using the JavaScript V8 parser, Node is extremely fast, scalable, and is an event-driven programming model (not that I entirely comprehend EVP). After reading this article and multiple other Node-related articles, I can't say I still fully understand how Node.js works. I think Node is one of those technologies that you can't effectively 'learn' until you've actually played with it. The Mashable article I listed does a pretty good job talking about the background of Node and some practical applications.

Inspiring Websites

Topic: Mutant Labs
Link: mutantlabs.com

Inspirational websites really speak for themselves. I'm not a graphic designer, but I can appreciate attention to detail and mastery of a craft. Click around and I'm sure you'll see what what I'm talking about.

Cool Snippets of Code

Topic: Practical Uses of Ruby Block
Link: viget.com/extend/practical-uses-of-ruby-blocks

If you develop in Ruby, odds are you write a lot of these types of blocks - you assign an object and then wrap your block of code around an 'if object' statement. I think these are fine and they take up the same amount of code as the new way; however, I like the clean assignment and readability that the new code proposes.

Rails Gems Worth Checking Out

Topic: Facebook OpenGraph to ActiveRecord Gem
Link: github.com/rubenrails/acts_as_opengraph

So this is really cool. Facebook integration is everywhere these days. What if you were able to take a model and turn its objects into Facebook Open Graph objects? That's what acts_as_opengraph does. For example, what if you were building a blog engine or basically any type of model that has a show page that will need Facebook integrated on it. Well all you do is take the model and add the dependency like this:

Then you just integrate this into your layout and views wishing to use the Open Graph:

Hopefully you found some of these interesting as I have about 30 more articles that I'd like to post in a similar fashion in the upcoming months.

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

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