A Few of My Favorite Things: scope and Symbol#to_proc

Let’s say you have a User model. Let’s also say that you want the ability to archive your user records.

So, you add a boolean attribute called archived that defaults to false which can be set to true in order to archive your user records. Now you can look for archived records by performing the following query throughout your app:

Well that’s nifty… until you realize that you’re having to write out that blasted where() statement in five billion places throughout your application. Is that DRY? Quite the opposite, I tell you! What happens if you change that attribute’s name, you’re bound to miss at least a few instances of it in the change. For the love of all that is holy – this has just become a horrible solution!

Four solutions to this problem spring to mind: one is outright dumb, two are common and one is simply beautiful.

The first option is to put a query like this in our views.

Seriously, if you find yourself putting ActiveRecord queries in your views, just go back to PHP, please. If you’re simply new to Rails and honestly don’t know any better, read on. The second option is to put this query in your controller.

While this isn’t necessarily a bad solution, it tends to get repeated… a lot in some cases, which once again goes against the “Don’t Repeat Yourself” mantra. Another solution is to move this logic into the model. Well, well. You’re one smart cookie, you! Skinny controllers, fat models. Let’s move this clunky query into the model!

This is much prettier! But this method is gonna get all kinds of lost in any respectably sized model. This used to be the best way to store a query for frequent use until Rails 2.1 was released with named_scope in its bag of tricks. Now, in Rails 3, named_scope has a new persona, and it’s here to… fight crime… and stuff.

Enter scope

The scope method belongs in the list of incredibly useful model methods along with associations and validations. This method expects two arguments; either a name and a condition or a name and a block. We can easily convert our above query using the name and condition combination.

This can be used to grab all of the archived users, similar to the previous example.

Delightful! Seriously, I feel like I just ate a Hot Pocket. Oh, actually, that doesn’t feel good at all. But this scope looks great! It’s clean, on one line and behaves beautifully.

So, how would we use a block with scope? Think of any situation where you’d want to pass data into a query. This is where you’d use a block with scope. In our example, we want to return all users with whatever role we pass it.

Now we reference the scope, passing a role into it as an option.

Holy cow! So, basically we can take a massive query and slap a small scope name onto it and reference it whenever and wherever we need to. If this query changes, we change it on one place. Graceful, elegant and easy to update.

Now that you know how scopes work, I would be a horrible teacher if I didn’t introduce you to default_scope. This beast will allow you to specify some query goodness that you want appended to *every* query you run on that model. Using our example above, what good would an archived scope be if User.all returned the archived users too! Not very much use in my book. We can use default_scope to tell the model when we search normally, we only want the users who are not archived to be returned.

Now when we do a search for users, it will only ever return users who have archived set to false. Slick! But what if we want to get around that for a query or two? Let’s say we want to count ALL users, archived or not. We’d use unscoped here. Let’s pretend we have 75 users, 5 of which have archived set to true

Symbol#to_proc

One more thing. You may have recognized a reoccurring bit of code throughout my examples.

We’re iterating through the list of users in the @users instance variable and outputting the name attribute of each. If you only need one attribute from each record in a list, you have just encountered one use case for Symbol#to_proc. Instead of an each block, we could simply use the following:

This list of names can now be used however you like. Perhaps a nice join() method would meet the need?

Now, go call your mom and tell her all about the wonderful things you learned here. After that, go forth and use scopes and Symbol#to_proc like the mofo you know you are!

Textmate’s Twilight Theme for Xcode

I’ve used the Twilight theme in Macromate’s Textmate since the beginning of my reign of terror using Textmate around 2006. Moving to Xcode, I really liked the tools and features but not the look and feel… at all. This helps.

Twilight theme in Xcode

Twilight theme for Xcode 3
Place this in: ~/Library/Application Support/Xcode/Color Themes
Select it in ‘Preferences > Fonts & Colors’

Download Twilight for Xcode 3

Twilight theme for Xcode 4
Place this in: ~/Library/Developer/Xcode/UserData/FontAndColorThemes
Select it in ‘Preferences > Fonts & Colors’

Download Twilight for Xcode 4

If you have any feedback, hit me up on Twitter (@slant).

The transition from del.icio.us to Google Bookmarks

Well, the day has finally arrived. del.icio.us is going away and if you’re anything like me, your bookmarking habits have come to a confusing halt. What’s next?

I’ve chosen to give Google Bookmarks a shot. It’s no where near as integrated with Chrome or other services as I would have hoped, so I’ll be explaining how to create an environment that distracts as little as possible from your normal use while allowing you to save bookmarks as you see fit – as you are used to doing.

I have personally grown quite attached to Firefox’s del.icio.us plugin which provided a sidebar for searching through all bookmarks by tag or title. After moving over to Chrome and not having this, I found myself using del.icio.us much less – the worst part is, I watched it happen! I wasn’t sure how to best use del.icio.us having moved from a very well integrated plugin to, what I consider to be a poor implementation in Chrome. I had a shortcut to save things, but no shortcut to quickly access my bookmarks.

The first thing to do is to get your bookmarks moved over from del.icio.us to Google Bookmarks. The method I ended up using is a script written by Mihai Parparita which can be found here. This script is pretty powerful, importing my tags (as labels), urls and titles. The only thing it didn’t bring over were the dates each bookmark was saved.

Now that we have all of our data in Google Bookmarks, how can we use if effectively. If you’re using Firefox, there are a few solutions out there. Otherwise, if you are using Chrome, Safari et al, we’re stuck with making our own solution.

The first thing I did was to move things like my Instapaper ‘Read Later’ and Bit.ly links into a folder called “Save to” on my Bookmarks Bar. I then grabbed the bookmark link:

Google Bookmark

This can be dragged directly into the new “Save to” folder on the bookmark bar. This can also be found here. Clicking this provides us with a form to save new bookmarks. One down, one to go.

Now, how can we easily access this list? Saving a bookmark to Google Bookmarks is a great start, but we’re using Chrome – it’s natural to just search for things in the location bar directly! Why this should this be any different? Assuming you’re using chrome, we can accomplish this by adding Google Bookmarks to the list of Search Engines. Open Chrome’s Preferences window.

Chrome Preferences

Click the “Manage” button on the line that says “Search” followed by a dropdown list. You may be surprised by the number of search engines you have in here. click the + symbol below the list to add a new search engine. We have two options at this point. If you liked searching by tags on del.icio.us, I’ll be providing a tag-only search option here. I’ll leave that up to you. Add a logical name, likely “Google Bookmarks” (or “Google Bookmarks by Label” if you’re planning the tag-only route). The keyword should be simple painfully simple, such as “gb”. You will be using the keyword every time you want to search through your bookmarks.

Lastly, the URL you use depends on your chosen method of search. If you want the ability to search through everything (bookmarks names, labels, etc):

If you want to search through labels only:

I personally created one for each using the keywords “gb” an “gbl” respectively. I am a tag fiend, so for me, the latter option was the clear answer.

Once you have this setup, open a new tab, move your cursor into the location bar and type your keyword, then hit tab, then type your desired search criteria. Hitting tab should replace your keyword with the name you gave this search engine. If not, retrace your steps. Essentially “gb[tab]something” should do a search for anything related to the phrase “something” (assuming your keyword was “gb”).

I’m eager to see if this satisfies as a del.icio.us replacement. So far, sadly, it seems just as good as del.icio.us’ integration into Chrome (I say sadly since I have a feeling that this was the very problem that caused del.icio.us to decline – lack of solid integration). I will be giving this a solid try over the next few weeks. If you give this a shot, let me know on twitter (@slant) how it goes!

Optional Tags in HTML5

I’ve been learning a lot about HTML5 lately, and have found much of it to be pretty easy to adapt to. I found one bit of newly acquired HMTL5 knowledge blog-worthy: the fact that the <html>, <head> and <body> tags are optional!

After coding HTML since 1997, I’m pretty used to the standard elements for any new HTML or XHTML document (leaving out the good-practice bits for simplicity-sake).

[gist id="598365"]

These have become the staple of any Web developer. As you might imagine, the fact that the same document can be written as follows was quite a shock!

[gist id="598367"]

We’re free! We’re free!

Not quite, I’m afraid. As it turns out (I know this will be a shock to some of you), omitting these tags has a few undesirable side-effects that will leave some of your visitors dead in the water. The first of our offenders is the lack of a specified primary language for the document in the <html> tag. Excluding this will prevent screen readers from being able to determine the language of the page, preventing your site from being read consistently.

The next issue is derived in my favorite browser of all time – Internet Explorer (can you hear the sarcasm oozing forth?). Apparently, Microsoft deemed it necessary to prevent a page’s HTML5 elements from rendering correctly in the absence of a <body> tag, even with the hack of initializing the elements in Javascript, IE gets all pissy and still treats the elements as red-headed step children. Why? Yeah, we don’t know either.

Lastly, omitting these tags simply renders your code less readable. That one is simply something to consider. Those who know me well know that I’m a formatting nazi.

After all of this, the safest way to write our aforementioned code would be something like this:

[gist id="598376"]

So, what’s different about this compared to the old and busted version? For starters, we were able to shorten the doctype to simply “html”. In modern browsers, declaring a doctype is only used to trigger standards mode, but declaring something is necessary. Another difference is the missing quotes around en. Not a big deal, but it is certainly noteworthy that quotes are no longer required in order for the code to validate.

Listing Social Networks in Ruby

I spent a little time tonight working on The Enclave’s new member page. The site overall is the most beautiful thing in the world, but I have been using it as an excuse to plan more with Sinatra.

Tonight, I found the need to provide a way for our members to list their social networks should they choose to do so. The obvious way was to add a list of anchor tags. I found this to be rather distasteful. I mean, we are dealing with Ruby here, right? So, I started by considering what I wanted the UI code to look like. Would do I want to have to work with on a weekly basis. I came up with the following:

This would allow me to add as many usernames and networks as I desired. Perfect! So I began to work on the code that would make this function as intended. I came up with the following:

So, basically, I list all of the networks I want to use. This list not only includes the URL (and a place holder for the username), but any prefix or suffix for the displayed username for which I might find a need (i.e.: Twitter’s “@” in “@slant”) Next, the script iterates through my list, catching each network as it does so. Each time the script reaches a network, it proceeds through each username in the list, building an appropriate anchor tag for each one.

In the end, you have a beautiful categorized list of usernames, each linking to their respective page.

linkedin: ryanlcross | facebook: rcross | twitter: @slant, @cylenceweb

Fluid + MenuExtra = Even More Awesome

I just ran across an incredibly useful feature in Fluid, thanks to @takeo. The ‘Convert to MenuExtra SSB’ feature allows you to run a single site browser as a menu item at the top of your screen. Brilliant! I now realize that my life has not been complete until today. This is easily my new favorite feature of Fluid.

Why would you want to do this?

You seriously have you ask? Okay… I’ll humor you. Once I understood what this feature did, I immediately came up with a few benefits:

  • Keep Fluid apps that you rarely interact with out of the way
  • Keep Fluid apps that you tend to need quickly at the ready
  • Get a Fluid app out of the app switcher

I’m sure there are more reasons, but those are the ones that sold me. My use case was MOG, an online subscription music player. It uses a Flash interface for its player, which was a real disappointment to realize, but here we are.

What I didn’t want

When I started using MOG, I just opened it in Chrome, opened their player in the popup window, moving it to my media Space. First of all, that’s an annoying process, not practical at all for a service I want to use daily. They don’t have a desktop player yet, and from what I hear, it will be in Adobe Air anyway, of which I’m not a huge fan. Don’t get me wrong, they did a great job on the player’s interface, its just… well, its Flash.

Creating a Fluid app would surely be useful in keeping MOG distinct throughout my experience using the site, but its still a clunky browser window that doesn’t size correctly to the Flash interface of the player without – yet again – opening the popup through the site. So, what would be the benefit of creating a Fluid app for MOG?

At Last: Awesomeness!

This is where the solution I found came into play. I’ll just give you the step by step on how to get this running smoothly and let you decide whether or not its worth the time.

Creating the Fluid app

To start things off, we need to create a new Fluid SSB for mog.com.

Creating a new Fluid SSB for mog.com

Now open the new the newly created application.

Fixing an issue with Spaces

This next step is for those of you who use Spaces. If you don’t, feel free to skip this one: Open System Preferences followed by Exposé & Spaces. In the Spaces tab, look for your new Fluid app in the list below. In the second column, select Every Space for your app and close System Preferences. This will prevent some Space-switching grief when we move into MenuExtra mode.

This can also be accomplished from inside the application itself. In the app’s Preferences, click on the Behavior tab. Change the top option (Spaces Behavior) to “Windows Appear in all Spaces”.

Login and Fluid Settings

In your Fluid app, log into MOG. You don’t have to yet, but its easier to do it now while in this mode. These next two steps are critical for maximizing the awesomeness, so pay attention! Navigate to http://mog.com/player in your SSB to bring up the player, then hide the Toolbar, either through the Viewmenu or by pressing Cmd+Opt+T. Lastly, setting a Global shortcut is a very good idea. On the first tab in the app’s preferences, you’ll be able to accomplish this.

MenuExtra Time

Now, select the MOG menu option (or whatever you named your app) followed by Convert to MenuExtra SSB....

Select 'Convert to MenuExtra SSB...'

Accept the warning that pops up next. You will now see a new icon in your menu bar!

New icon in menu bar

Clicking this new icon will bring up the player in a popup window. It is resizable, but not scrollable. Furthermore, you can access this menu item from any Space now. Let me know if you find any other sites that work really well with this setup, or perhaps other benefits to using MenuExtra SSBs that I’ve not mentioned here.

edited by Ryan Cross

MOG icon

@takeo just threw this icon together which I think looks pretty darned nice in the menu bar. Thanks, Toby.

Custom Categories in iBooks

So, the iPad has finally arrived. I’m probably enjoying mine more than I should be.

I find myself particularly drawn to iBooks with regards to technical books. I am incredibly grateful to The Pragmatic Bookshelf and O’Reilly for making previously purchased ebooks available in the epub format, the format native to iBooks (as well as many other readers including Stanza, the iPhone app that had this capability a few years ago).

As much as I have been enjoying this app, I’ve been frustrated with how the seemingly arbitrary categories sort the books when viewing the them in list view. One such category was:

COMPUTERS / Hardware / Personal Computers / Macintosh

Seriously? Not only this, but the formatting was awful! Some were in partial caps while others used slashes and other various characters. It turns out the fix was really simple!

The Fix

In iTunes, under the Books library, start by right-clicking on an ebook and selecting Get Info. Heading over to the Info tab reveals the answer. iBooks is apparently using the Genre of the ebooks as the categories!

iTunes Get Info window

Meh. Okay, I can see how that makes sense. Come up with a way to logically organize the ebooks you have and go to town! I found that the technical books I currently have seem to fall under ‘Web Development’ and ‘iPhone Development’. Much better.

iBooks on iPad

Next complaint

I’d love to see categories make their way into the shelf view. There’s currently no way to sort the books found in this view.

Gmail, Unsubscribe Me!

After receiving one too many offers from EA to purchase a few of their products at a discounted rate, I decided that I’d had enough and parsed the email for the fated unsubscribe link. While doing so, I noticed something new. In the email’s header data, I saw an “Unsubscribe” line, where the value was a link (“Unsubscribe from this sender”). Doing a little research turned up a post on the Official Gmail Blog detailing this new feature which I’ve apparently found success in avoiding since July.

It looks like Google is only displaying this header for trusted companies, such as EA, since anyone else might just take your request as a cue that you want more spam.

“This only works for some senders right now. We’re actively encouraging senders to support auto-unsubscribe — we think 100% should.”

In the same post, Google is also letting senders of such email know how to take advantage of this new feature.

“… including a standard “List-Unsubscribe” header in your email with a “mailto” URL and, of course, honoring requests from users wishing to unsubscribe.”

Gmail has always had a pretty decent spam filter – in fact, that’s why I jumped on board with them as my primary email provider back in the early beta days. This is just one more reason to stick with them. I still wonder why they’re only the third largest email provider. Perhaps its the same reason why Internet Explorer is still the most commonly used browser… I am change, fear me!

Journey to Snow Leopard

Like many, I was in my local Apple Store on August 28th to pick up their newest operating system update, Snow Leopard. Despite hearing about some compatibility issues, my inner-first-adopter got the better of me and since it was basically the beginning of a weekend, I began down the path of the upgrade.

Luckily, I walked out of the installation process unscathed for the most part with only a few minor issues to deal with.  One example would be that Phusion Passenger was no longer working – but mongrel was – so that was livable.  Realizing that I’d not yet setup a decent database for development since getting my new MacBook Pro, I set to work on basically reinstalling the entire Rails stack to ensure that everything would be ready to roll when I get back to work on Monday.

I found a few fantastic resources to guide me through the majority of what I was looking to do including Hivelogic’s guide on Compiling Ruby, RubyGems, and Rails on Snow Leopard as well as another guide on Compiling Git on Snow Leopard.  I also found some great information on installing PostgreSQL on Snow Leopard. Lastly, I discovered a very short guide on compiling the PostgreSQL RubyGem for use on Snow Leopard (enabling 64bit compatibility).

Equipped with these guides, I successfully got everything upgraded and am now waiting for all of the other 10.6 bugs to pop up!

edit: A definitive guide in deed. I just found a guide for those of you who want to install things like MySQL and SQLite as well.

Cross-subdomain Cookies on Different Servers

So, I have two servers, each on a different subdomain of the same domain. We needed to send data from one to the other. Cookies seemed like the logical method, but the data that we needed to pass was actually coming from the second server. The solution I’m going to demonstrate uses an HTML image tag to invoke and retrieve data from the remote server. I’ve seen this solution before, never needing to try it for myself, but it’s actually pretty handy (even though I find it a bit too hacky for my liking).

We will assume that our domain is domain.com with subdomains one and two.

Let’s start with the image tag code of the first server:

Extremely basic. Just a URL leading to the remote PHP script. Now for the code in the file to which the image tag points.

In case you are not familiar with PHP’s setcookie() function, have a look at the last variable being passed: “.domain.com”. Note the dot before the word “domain”. This allows the cookie to be set and used by any subdomain on that domain. Had there not been a dot there, only the root of the domain would have been able to access the cookie.

Once the image tag is placed somewhere in the files which will be accessed by visitors on server ‘one,’ the cookie will be set once the page loads (loading the image tag along with everything else). After all of this has happened and the cookie is set, it can then be accessed from either server. On a side note, the “display: none;” portion of the image tag is necessary so the tag won’t render a broken image on the page.

One last point. In my example, I sent GET data directly to the target script and set it in a cookie without ANY validation. This is an extremely bad idea in a real world scenario. Sanitization is recommended at the very least. With that said, the resulting cookie in my example would have a value of “yoink!” since that’s what we sent the script in the image tag’s query string.