Brian McQuay

+menu-


  • Category Archives Web Development
  • Upgrade to Rails 4 already

    I’ve been developing a new application from the ground up built on Rails 4. I wanted to publicize my thoughts so far and try to encourage the weary to stay on the edge lest they face their own deprecation. Even though we’re extremely close to an official Rails 4 release there are countless gems out there that haven’t even begun to upgrade themselves and countless projects undoubtedly have yet to even discuss their upgrade path to Rails 4. While the upgrade from Rails 3 to 4 isn’t likely to be as difficult as it was from Rails 2 to 3, there will certainly be a handful of changes required. You’re either ahead of the game or you’re playing catchup. Don’t get caught without an upgrade plan while the rest of the community migrates to Rails 4. So enough preaching. Lets get into it.

    So far, I’m fairly happy with how few habits I have to change when working with Rails 4. The most notable change you’ll discover is strong_parameters. There’s a gem you can use already to get your application using strong_parameters while you’re still on Rails 3 and I highly recommend you start there if you’re doing an upgrade. If you’re not familiar with strong_parameters, it basically gets rid of attr_accessible and moves the logic into the controller. Initially, this feels a bit strange because we’re used to thinking of the model as sort of self encapsulating in a way. It does what it needs to do to manage the data. The problem with attr_accessible is that it never really allowed for much flexibility and was a fairly primitive and rigid approach to mass assignment protection. strong_parameters moves that logic into the controller where, once you’re used to it, it feels much much more powerful, customizable, and arguably better organized. It allows you to embed business logic around your mass assignment protection for instance. One example is managing a record as a user versus an admin. An admin might be allowed to update a bunch of attributes that the user isn’t allowed to update. Before strong_parameters, we’d end up having to grant all the records both the user and admin could update in attr_accessible and then customize the controller’s update action to manually set each parameter the user would be allowed to change. This ends up making a big mess of code when you compare it to how strong_parameters handles it. strong_parameters lets you specify different sets of attributes allowed for the user and the admin and it does it in a way that eliminates the need for attr_accessible, cleans up the update actions, and keeps the mass assignment protection logic much dryer and much more useful. Here’s how we might do it without strong_parameters if we want to allow a user to edit name and description but only the admin to edit contact:

    Normally I’d make a separate admin controller for this but for the sake of the example lets assume this is ok. Obviously this will get out of hand if you really want to be safe with your attr_accessible because with each new attribute you end up having to manually assign it in the controller. Here’s how you’d do the same thing with strong_parameters:

    Now you can see pretty quickly how much more powerful this is. It allows us much finer grained control over mass assignment protection and lets up keep our code clean while making it more secure. After you get used to it, you’re going to love it.

    The second big gotcha you’ll discover is turbolinks. Its a gem that’s enabled by default and as soon as you start crafting some Javascript for your application you’ll discover it. Basically your Javascript won’t work correctly in a lot of cases because of turbolinks. For those not familiar with turbolinks, it a way to speed up page loads by doing it through turbolinks Javascript instead of doing an actual browser page load. Turbolinks takes a typical anchor tag and fetches the page. Instead of rendering the entire page it does some trickery with the DOM and replaces the BODY contents, page title, and modifies the displayed URL so it looks correct. What this does in effect is it prevents your browser from having to go fetch the CSS and JS all over again for each page load. This can save a ton of time especially when you’re loading bulky JS frameworks or fluffed up CSS like Twitter Bootstrap for instance. The unexpected side effect of course is that your JS and CSS isn’t loaded when you’re expecting it to. Its a trivial to fix your Javascript once you know what’s happening though. Overall, I like turbolinks and it’ll generally reduce the amount of data you have to transmit but its a strange default addition to Rails in my opinion. Its almost like defaulting will_paginate as a gem. Sure its useful but does it need to be included by default? Either way though, you’ll learn to love it.

    Here’s how you might do something before turbolinks and discover it no longer works:

    Basically this is saying to initialize a datatable once the page is loaded. Turbolinks isn’t going to even look at this when you visit the page via a turbolink though. Its just going to replace the body, page title, and url. Here’s how you’d do it if you’re using turbolinks:

    What this is doing is it defines the load_datatable function and calls it like you’d normally do when the DOM is ready if you manually entered the URL or did a manual page refresh. The last line is what you need to learn though. It tells turbolinks to call that function when the page is loaded with turbolinks. So it replaces the body, the title, and the url and then it will execute the load_datatable method and everything will work how it used to work.

    There’s a few future deprecation notices that you might come across as well but for the most part its fairly painless. However, there’s a ton of gems out there that aren’t compatable for one reason or another. The handful that didn’t work that I’ve investigated were basically written poorly to begin with or made heavy use of attr_accessible which will undoubtedly make upgrading those more difficult. However, there are a bunch of gems already working on Rails 4 support and its only a matter of time before you’re going to need to upgrade yours as well. I’m running everything off the latest from github and its working pretty good. I haven’t had any gems’ repo ruin my bundle yet either. Rails 4 is probably the most stable new Rails version that I’ve seen before and I’ve seen every major release including version 1. The early days everything was a mess and barely worked right. Rails 2 was the first really stable release there was and upgrading to Rails 3 was a nightmare usually. Despite the history, however, this latest release is going to be the easiest upgrade there has ever been in the history of major Rails releases. Its simple, its stable, and it still has that new car smell. So what are you waiting for? Upgrade to Rails 4 already.


  • Generic Email Resque Job

    I was working on a project recently that uses Resque to queue jobs. One of the main things they use this for is to queue email jobs so they don’t hold up the user. The way things were initially implemented and the way I’ve seen it done in the past is they had a separate job for each email. This wasn’t going to scale very well and was going to create a big mess of code in the long run because we’d have to manage a separate Resque jobs for every type of email. This post is about my solution to this problem. Its a consolidation of email jobs so you can have one generic email job and reduce the amount of code in your application by a lot.

    The first step is to define the actual Resque job:

    What this piece of magic does is it allows us to pass in any mailer with a mail method, parameters, and destinations. It loops through the email addresses we’re going to send to and it fires off the mailer we send it. Here’s an example of how to use this:

    Notice we’re not passing in the entire mailer but just the class name and the :welcome token. The Resque job uses that to instantiate the correct mailer and call the correct method and that only happens once its out of the Resque and executing. The queue stays slim and its very dynamic now. You don’t need a new Resque job for every email at this point. The only caveat now is how you handle params in the actual mailer. Here’s an example:

    Notice that very generic params we’re passing in. Instead of creating a welcome method that takes in each variable separately, we just use a generic params hash instead. You could easily change this to make it so it accepts a dynamic number of “*options” for instance if you prefer.

    I was very pleased with how this turned out and how much code its going to let us condense that I had to share it. I hope you find it useful.


  • Improving your Development Process with Tests and Code Reviews

    I’ve worked with a lot of different teams in the past and I’ve seen a lot of variation with how those teams approach things like tests and code reviews. With this article I hope to shed some light on what practices work, which are destined to fail, and provide some advise on how to improve your test coverage and code reviews.

    Test Coverage
    Very often I encounter projects that have either no test coverage or so few tests as to make the tests effectively useless. In order for your tests to really serve their intended purpose of improving the modularity and reliability of the code, they need to be comprehensive enough for it to really work. If your tests are sparse, most of the bugs in your app will just fall between the gaps in your test coverage. Poor test coverage tends to result in less modular and more complex code. That less than ideal code ends up mixed in with better code that does have tests. This mix of good and bad code increases the complexity of the app more than it would if you had just all good or all bad code sometimes. It only takes one bad apple to spoil the bunch and the same goes with software. Bad code will spoil good code and bad practices will spoil good practices. Unless you have strong and broad coverage and a solid process for maintaining test coverage, you’re tests are mostly useless and you’re likely better off not even wasting your time doing tests. Don’t get me wrong, I’m a proponent of as close to 100% test coverage as you can possibly get. If you’re test coverage is more like 10% where you sometimes make tests and you sometimes don’t then you’re just wasting your time making tests. You’re either committed to complete test coverage or you aren’t. Anything else and you’re just spinning your wheels because you think it feels right to make some tests every now and then. Sparse tests are worse than no tests because you have a false sense of a proper process and because you’re wasting time building tests that cumulatively just amount to wasted time. Unless you’re close or over 80% code coverage, you probably have a process problem not a test problem.

    So if you’re committed to full test coverage, how do you go about making sure everything is actually tested? This is where code reviews and test driven development come into play but first lets discuss code reviews in general before we tie the two together.

    Code Reviews
    I often hear teams tell me that they only do code reviews occasionally or that they would really like to start doing more code reviews. My advise to them is always the same “You’re doing it all wrong.” If you’re telling yourself something similar its because you’re not building code reviews into your development process. I’ve seen teams try to impose a code review schedule where one a week or so the whole team would sit around and look at some code together as a group. No one is usually very interested and very little comes out of it than making a project manager feel like they’re doing the project good by having occasional code reviews. The problem with this approach is that no one is really all that engaged during the review and you still end up with tons of code making it into production that hasn’t been reviewed by anyone but the developer who committed directly to the master branch (ick). The only code reviews that I have ever seen actually work long term are those built into the development process. Here is one typical flow that I have seen work well in numerous teams.

    First, a developer creates a new branch for whatever task they’re working on. When its complete, the developer commits the code to their branch and creates a pull request to merge that branch into the development branch, or master if necessary. This is the first big step.

    Next, before ‘developer A’ goes onto another task, they look for pull requests from other developers. If there’s a request waiting, ‘developer A’ comments on the pull request that he’s reviewing it and then does a code review on it. If things need fixing or changing, the ‘developer A’ comments on the pull request. The original developer, ‘developer B’, then makes the necessary changes until ‘developer A’ is satisfied and does the merge. This dialog between the developers boosts information sharing, improves code quality, and enforces test coverage. Once the pull request is merged, ‘developer A’ finally moves on to either another pull request or grabs a new story to work on.

    What this effectively does is it makes sure that all code that gets merged into the development or master branches has been reviewed by another developer. Only when you build code reviews into your process like this will you be able to be comfortable knowing that no one was able to slip code in that wasn’t reviewed by at least one other developer.

    Code Reviews Enforce Test Coverage
    This is where this kind of code reviewing development process merges with your tests. When you have all your code being reviewed, you can also use it to make sure that all code is tested. Its the reviewer’s responsibility to make sure they’re comfortable with the test coverage of the committed code. All code should have tests before a pull request is created and the reviewer acts like an enforcer. The only way for any code to get merged is through this process and so you will have good test coverage and you’ll have all your code reviewed. Its a win win situation.

    I don’t really need to delve into the nuances of TDD since there’s a million posts already out there about TDD. However, I must say that if you do build your test first in a true TDD style you will definitely not forget to make tests before you commit your code and create a pull request. The tests are the first thing you build so you never end up forgetting them. They’re there before your actual code even exists and they serve as a guide for keeping your code modular and testable.

    This is such a great development process that not only will it likely solve your test and code review problems but more importantly it also helps elevate junior developers. The process of reviewing code and making sure your own code passes the scrutiny of whoever is reviewing it tends to increase the quality of everyone’s work overall. If you’re wishing you had better test coverage or your team was doing more code reviews then you need to rethink your development process.


  • 3 new I18n gems for your Rails 3 app

    I’ve been busy building 3 new translation gems for a new application I’m working on. The first is i18n-country-translations. It breaks countries down into their standard country codes and adds translates for different locales. This gem can be easily incorporated into other gems or apps that need I18n country translations. Just add this to your Gemfile:

    gem 'i18n-country-translations'

    You can grab the source and more information here: https://github.com/onomojo/i18n-country-translations

    The next gem I created uses the i18n-country-translations gem to make a country select that automatically translates the country names in the select drop down to the current locale. Just add this to your Gemfile:

    gem 'i18n_country_select'

    You can grab the source and find out more here: https://github.com/onomojo/i18n_country_select

    Finally, no app that has any dates displayed to users can be complete without taking into account timezones. The last gem is i18n-timezones and just adds timezone translations which can easily be included into other gems or directly in your app. It also adds a convenient ActiveSupport::TimeZone override of to_s so that it takes the current locale into consideration. This makes it extremely easy to add timezone translations. Just add this to your Gemfile:

    gem 'i18n-timezones'

    You can grab the source and find out more here: https://github.com/onomojo/i18n-timezones


  • Investing in myself: Realizing my value as a programmer

    Being a programmer, you have an invaluable skill that you need to learn to harness. Investors realize this already which is why they’ll spend stacks of cash to have you build them something that’ll someday be profitable. Large corporations realize the value in good developers and sometimes bend over backwards trying to retain their top talent. To be able to program well is a skill that people clearly value but why do programmers tend to place such little value on their own talents?

    I know amazing developers who have spent the last decade building other people a fortune in IP while spending very little of their time building their own software. While its easy to look at the paychecks coming in and be content with your progress as an individual, when you put your progress into the context of intellectual property ownership most developers are left with empty pockets. Investors and businessmen use developers to build intellectual property for their businesses. They pay good money for a developer’s time along the way and usually the developer moves onto something else within a few years and the business finds someone new they can use to extend their growing IP treasure chests.

    When I look back on my own past decade, I’ve seen plenty of cash come and go yet the only thing that remains is the software I’ve built for myself in my own time. I put my time and effort into the context of IP and suddenly the value I place on my own time and skill begins to rise. I recently read an article geared towards investors that was recommending keeping good developers on your side at all costs. It argued no matter what a developer was building it was better to keep them busy building you IP and on your team than to lose valuable talent. I read that and taking the context of IP and the value of my time into account I asked myself why I wasn’t spending more of my free time extending my own IP treasure chest? I listened to the advise of that article to investors and I’ve committed to investing more in myself.


  • Upgrading Webster’s Classroom from Rails 2.3 to Rails 3.1

    I’ve recently tasked myself with performing a major upgrade for Webster’s Classroom. It includes both a complete site redesign and an upgrade to the latest version of Rails. We all know its a bit of a pain to upgrade from Rails 2 to Rails 3 but the longer you put off the upgrade the more painful it becomes. The app was written as a proof of concept many years ago and despite its growing user base it doesn’t have a strong enough foundation to allow it to continue expanding. We build it too quick and sloppy years ago and as a result we are testless and in need of major refactoring.

    The lack of tests actually makes the upgrade easier in some respects because instead of having to hassle of fixing a bunch of sloppy tests I’m building everything from scratch both the app and the tests. The refactoring needed for this upgrade is like writing the application from scratch anyway. The existing code I’m using more or less as a rough sketch of feature requests and I have full intention of throwing all that code away if it makes sense to in this new context. Instead of trying to upgrade the inline Prototype Javascript to jQuery and UJS piece by piece, I’ve decided its best to just throw all the old Javascript out the window and start fresh. I’m committed to getting as close to 100% test coverage as possible these days so as I’m doing the upgrade and redesign I’m making damn sure there’s proper tests in place this time around.

    I’ve upgraded a handful of apps to Rails 3 from Rails 2 already and in the past I’ve started off trying to upgrade within the current code base. I’ve had numerous problems with this approach and unless you’re really meticulous on every single file, you’re going to end up with a bunch of old junk files laying around and likely some missing new ones that you’ll want. This time I’ve taken a different approach and started off with a fresh default Rails 3.1 install and began moving over the legacy code file by file. I’m happy with taking this approach and instead of trying to take my Rails 2 code and upgrade it to Rails 3. Starting with a fresh Rails 3.1 code base and moving over code where it needs to be has given me the chance to move things into places they ought to be like moving code outside of the environment configs and into initializers. If I had just tried to upgrade the old code inline, I wouldn’t have spent the same amount of attention on cleaning up that mess. Once this upgrade it deployable, Webster’s Classroom is going to be in a position to really expand dramatically and rapidly.


  • Recent developments

    Its been quite some time since I posted anything so I feel a necessity to publish something. I’ve started many posts since the last one but I never really liked how they turned out so I discarded them. I’ve learned plenty of new things which I tried to share but never had enough time to devote towards a solid post about any of it. Considering that time seems to be always something I’m lacking, I will just post a random rant about what I’ve been up to.

    I’ve started working on a Facebook app for a client called Redflag. Its an app that lets parents monitor their child’s Facebook accounts for potential bad friends. Its a fairly complex app written in both node.js and Ruby on Rails. Node.js was something I hadn’t worked with before this project but I really like it. Its a little confusing thinking in terms of asynchronous execution of code in our app because there’s a ton going on behind the scenes and its a little difficult to visualize how thing all tie back together through callbacks. The complexity of our node.js backend makes it extremely difficult to test well but we do have a small but growing suite of jasmine tests for it.

    I’ve been continuing to work with San Francisco Soup Company on their kitchen management application and have hired another developer, Jose, to help out. He’s an excellent developer and writes some really solid code. We’ve migrated the site to Rackspace’s cloud and I’m really liking Rackspace over Amazon’s EC2 these days. Their web interface is much more usable and I can actually get ahold of someone when there’s a support issue. The server seems to run much faster than similar EC2 instances and is cheaper so I’m pretty happy with Rackspace so far. We’ve been working on refactoring the code and building a more comprehensive test suite which is coming along extremely well.

    More interestingly, I’ve started partnering with different businesses to expand my development and design resources. These additional resources will allow me to expand Onomojo in new directions and produce better results than I could just by myself. My focus is on partnering with companies that have solid development processes or are at least adaptable enough to conform to my own methodologies and best practices. By partnering primarily with businesses instead of individual talent, I will be able to provide more consistant results for my clients without the HR headache that comes with managing a team of remote developers. I have an agressive growth goal for 2012 and with the partnerships I’ve been building I believe Onomojo is in a good position to realize those goals.

    I’ve also made great progress towards getting back into graduate school. I am working on a plan that will let me continue being CEO of Onomojo but allow me the flexibility to get my PhD. I’ve retaken the GRE and got a great score. I’m still working on narrowing down my school choices and drafting my applications. I don’t expect to apply anytime soon though. I need to have my ducks in a row before I jump back into academia. I won’t be applying until next year at the soonest with a starting date of 1.5 to 2 years from now.


  • Earthpay – Online Payment processing startup committed to donating collected fees to charity

    This site has been a long time coming. I pretty much finished the prototype about 6 months ago and the CEO is working on funding to take it to the next level. Its a great way to easily contribute to charities around the world without costing you a single penny. It basically takes profits collected per transaction and donates them to your selected charities or causes. By integrating into your existing shopping cart, you can help save the world without costing you a single penny more than what you’d already be paying in processing fees. Take a look at the site and if you’d like more information please don’t hesitate to contact me or one of the other contacts on the site.


  • My Goodbye Letter to Engine Yard

    That response sounds familiar but really isn’t that comforting or
    realistic. You’re suggesting its rare to have instances disappear yet
    it happened twice in less than 6 months. You’re suggesting I upgrade
    to a more expensive server which may or may not solve the problem. You
    don’t know what causes the instances to disappear but for some reason
    a more expensive instance solves the problem. I’m not sure how those
    dots are connected but it certainly doesn’t add up to me. You want me
    to spend more money per month without any real justification,
    quantitative data, or explanations.

    To summarize:

    * You don’t know why instances disappear.
    * Its rare for instances to disappear.
    * The solution is to spend more money per month.

    From my perspective, you still haven’t resolved the underlying
    problem. You suggest maybe hardware but hardware crashes twice in 6
    months? That doesn’t sound realistic. The issue that concerns me is
    that you haven’t addressed the underlying problem of why the instances
    disappeared. You’ve only offered a solution that has no connection to
    the actual problem: Get a better server. Of course, I could just go
    straight to Amazon and bypass EY altogether if I were to get another
    server.

    Without really understanding why the instances are disappearing it
    points to a bigger problem at EY than just this issue. It points to a
    lack of concern for your clients, a lack of understanding of your own
    technology, and a fundamental problem in how you attempt to solve the
    problems presented to you. Its a ‘shuffle it under the rug’ approach
    to solving your problems which doesn’t bode well with me. Your
    solution is, simply put, one without any technical merit. Anyone in
    sales could have given me the same answer. If I were to refer clients
    to EY and they had other problems that you couldn’t figure out would
    your solution be that they need to upgrade their servers?

    I appreciate your delayed investigation into the issue but I
    definitely won’t be moving more of my clients to EY anytime soon. I’m
    actually glad you reached out to me recently because its given me the
    motivation to review what I still see as this outstanding issue. As
    such, I’ve decided to cancel my EY account.

    > From: EY
    >
    > X and Y asked me to follow up with you on this.
    > First of all, if someone on my team dropped the ball on getting back to you,
    > we apologize. I will follow up with the engineers on my end.
    > Re. instances disappearing – I found and reviewed the ticket for when this
    > happened. It appears that it was no longer possible to SSH into your
    > instance and when our engineer tried to terminate it, it was stuck in a
    > shutting down state. I can’t answer why this happened in this particular
    > case, but out of the several thousand AWS instances we manage on the EY
    > AppCloud, occasionally we have observed that an instance can disappear or
    > become unresponsive. This can happen, for example, if the physical server
    > it is mounted on fails. The few times we have seen it, it has been for
    > Small instances, which is what you had. Our default AWS instance size for
    > EY AppCloud is now Medium, which we to date have not observed issues with.
    > Hope that answers your question – and feel free to contact me for any
    > additional questions about this.


  • EngineYard default configurations strike again

    It was just brought to my attention that my company’s homepage was pointing to the wrong app. This has happened a few times since I’ve switched to EngineYard. They don’t include www aliases in the default nginx configuration so you have to add them with a keep.domain.conf file. I recently migrated my company site to a new instance and left the default configuration. When I checked to make sure the app was setup on the new instance properly, http://onomojo.com , it worked fine and I didn’t think anything of it. Of course, I didn’t test http://www.onomojo.com which ended up pointing to an app that is still in the early phases of development since I didn’t customize the nginx config. What a huge goof. No wonder I’m getting mixed responses from potential new work lately. If you’re reading this and you saw the awkward half broken site with the test video please revisit the site again.