Rails Scopes, Using Strings for Queries

Scopes in Rails are great, but there is a certain way to write scopes that will prevent debugging and possible hair-loss in the future. If you practice TDD, this seems ‘premature’ but I see it as writing the solution to the problem differently, not prematurely.

You will experience problems with scopes when you start to create advanced queries, queries that leverage joins and use strings.

For example, let’s look at the Post model as used on the Ruby On Rails Guide:

class Post < ActiveRecord::Base
scope :created_before, ->(time) { where("created_at < ?", time) }
end

This will work great, until we perform a query like the following:
Post.joins(:comments).created_before(Date.today)
Since we are working with the Post object, we can use the created_before scope. However, when we look at the actual query executed, we will see the following:

SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (created_at < '2014-05-06')

As you see, the created_at is not provided a table name, so it isn’t ‘scoped’ to the Posts table, so it will throw the following error (I’m using SQLite for the example):

SQLite3::SQLException: ambiguous column name: created_at

If this were a scope that simply needed the Posts on a specific date, we could bypass the string query and use the assignment type, by using the hash syntax:
class Post < ActiveRecord::Base
scope :created_before, ->(time) { where(created_at: time) }
end

But it’s not, unfortunately.
So, the way to solve this issue, is to limit your scopes to the table your working on.

class Post < ActiveRecord::Base
scope :created_before, ->(time) { where("posts.created_at < ?", time) }
end

By adding the “posts.” to created_at, we can now use this scope in a joins clause, or in another crazy query that is still built on top of ActiveRecord and it will not break anything due to the nature of how ActiveRecord generates queries.
TL;DR: Add the “<table_name>.” to the column names in your scopes that use strings. I’ve posted the project on GitHub, for testing pleasure.

Basic Security is Broken

A co-worker of mine is currently dealing with the possibility of identity theft. He has been doing some online trading of commodities and told me that he had experienced some login issues stating that he was currently logged in when he wasn’t, furthering his suspicion of identity theft. When I asked if his platform used two-step authentication, he asked “what’s that?”

When I logged into my investment site, I decided to change my password. First problem: 6-12 characters, use of non alpha-numeric characters was prohibited. That’s a weak password to me. Even with the multiple security questions (which, if you do some research could be easily answered), there are no other initial security measures. Second problem: after looking for advanced security, such as two-step authentication, I found none.

To my dismay, it is not just trading platforms that are broken (from a security standpoint), but a good majority of other platforms and systems as well. Today I filled out my NCAA bracket for my group of friends. When I was sent the group invitation over email, I was rather peeved that the password was in plain text. After clicking the link, it appears that the outside site provides a redirect to the NCAA site, which issues a GET request as so, where XXX is the group ID, and YYYY is the freaking password.

http://bracketchallenge.ncaa.com/#group?group_id=XXXX&password=YYYYY

Even under the assumption that group passwords are not important, you should still not issue them as a parameter in a GET request over HTTP.

I think any site/platform that has actual money invested or access to bank accounts should at least allow for stronger passwords and two step authentication. A lot of these systems are older, but these companies have the resources to accomplish these tasks. Blizzard does it and so does Google – and they really don’t hold a direct line to financial and completely personal information. Steam works great as well, storing and requiring computer authorization through email, adding a layer to what systems can actually be authenticated.

I think there is a lot that can be done and a standard baseline that should be established for security. We exist in a time when such systems using archaic passwords requirements and lack access security should be brought up to speed, especially from companies that can afford to.

Bad Source Control

I work on small team with ancient source control* – namely SourceSafe. It’s horrible. Why? Mainly because it slows the team down – tremendously.

Workflow
We work synchronously. Two developers can’t work on the same code because they then have to also be integrators – figuring out how to meld their code together – and you always miss something. In an environment where there are no code tests and everything is dynamically linked, you don’t find out what breaks until that code is run – which could quite literally be weeks later due to the sheer size of the application. When the bugs are discovered, the cycle starts over, increasing the time to when the bugs are fixed.

Commit History
Sometimes you break something – or someone else breaks something. Trying to find out what broke by going through the history is tedious, especially when there’s no good method of representation. In a good source control, you can go back to tagged versions that worked and compare files. If not, you’re literally sifting through tons of commits trying to make out what is what. That’s time lost.

Commit Messages
I love Git. One reason I love it is because it basically forces you to provide a commit message. You can skip it, but you will always go through that prompt screen / have to go out of your way to say that you have no message. Some VCSs make it optional (*cough* SourceSafe *cough*). When looking through commits that have no messages, you have zero clue about what changes without comparing commits to each other.  A simple message such as ‘fixed misspelled word’ could save me minutes in terms of comparing two files and scrolling to the actual change to see what it was. Granted this is also do to the person not adding a message, but the wall to prevent them is not there.

Branches
You don’t know how awesome branches are until you don’t have them. Spiking something? Create a branch. New Feature? Create a branch. Getting code from someone else? Create a branch. Different release versions? Create a branch, (layman’s way). When you don’t have branching, you revert to copying your files so that you have a backup. Which takes time, a lot of time.

Getting the latest version
Want the latest of code on the central repository? Depending on how it is setup, it could take you upwards of 5 minutes to go through all the project folders to make sure you don’t overwrite something that you might have locally. “git fetch” is an amazing thing.

So what’s my point? Poor version control systems slow teams down as time ticks away. They don’t allow for simultaneous progression of the code base and are painful to work with. Even if you have a good VCS locally, you still have to integrate with the central code base and work with the rest of the team. In the end, small development teams will lack the advantage of agility. Time is money. When you lose time, you lose money.

*Believe me when I say that I’ve pushed for changes.

Creation Anxiety

I’m going to diagnose myself with something I’m going to term: Creation Anxiety.

If I’m not creating, I suffer from anxiety.

I don’t know if it exists, or if it’s even a real thing. If I’m not coding, brewing, drawing, or working on something, I feel as if I’m wasting time. There are so many problems to fix and things to learn that sitting around creates a void of accomplishment.

So yeah, first world problems. <end rant>

YouTube’s Playlist Design

I was recently looking at some Defense of the Ancients (DotA) video guides when I realized how simple, yet highly thought out YouTube’s design is. Take a look at the image of their playlist.

youtube_playlist

At first glance, it just looks like a simple list with nothing really going on. Let me show some annotations:

youtube_playlist_annotated

A:

Notice the spacing between videos. Each video container has the perfect amount of spacing if it were to be placed in a void. Having them listed vertically just creates an easy to read, easy to find list of elements where you always know which video you’re currently looking at.

B:

Notice the very slight zebra striping. It’s so faint that you almost can’t notice it, yet, it’s enough for our brains to pick up on and distinguish the different elements. No fancy drop shadows, borders, or colors.

C:

The spacing to the right of each element is dynamic in that the box will grow, but the text will remain at the same width. This allows it to not be overcrowded with text and useless information. Here YouTube is relying on a descriptive video title that exemplifies the playlist content. It utilizes a snippet of the video text in order to entice viewers to watch – relying on what the content uploader provided. Want more views? Fit into the system.

D:

Clean cut corners that compliment each other. I talked about the spacing in A, but this is about the synergy. Very light border – much like the zebra striping – creates a clear distinction. You have a number for the video on the playlist which is semi opaque and the length of the video. Information that’s relevant, but not relevant enough that will be necessary when finding the video in the list – just when you’ve found the one you’re looking for. Once again, no need for fancy dropdowns, shadows, etc.

Overall, the cleanliness and simplicity of YouTube’s playlists are refreshing. After the web went through a phase of drop shadows and ‘look at the cool tricks I can do with CSS!’ it’s going back in the other direction, back to the core of what the internet is about: transfer of information. Focus on the product, not the fluff around it. If your users notice the fluff, you’re doing it wrong.