Let the App… Materialize!

materializecsslogoAfter I got the Google sign-in working well enough for my Rails practice web app, the first order of business was to build the basic skeleton. This was a great practice exercise to take the pieces I learned in the Ruby on Rails Tutorial sample app and build something of my own design.

The initial pass implemented basic functionality but it didn’t look very appealing. I had focused on the Rails server-side code and left the client-side code simple plain HTML that would have been state-of-the-art in… maybe 1992?

Let’s make it look like something that belongs in 2017.

The Rails tutorial sample app used Bootstrap to improve the appearance and functionality of the client-side interface. I decided to take this opportunity to learn something new instead of doing the same thing. Since I’m using Google Sign-In in this app, I decided to adopt Google’s design concepts to my client-side appearance as well.

Web being the web, I knew I wouldn’t have to start from scratch. I knew about Google’s own Material Lite and thought that would be a good candidate before I learned it had been retired in favor of its successor, Material Components for the web. One of the touted advantages was improved integration with different web platforms. Sadly Rails was not among the platforms with examples ready-to-go.

I looked around for an existing project to help Rails projects adapt Google’s design language, and that’s when I found Materialize: A library that shares many usage patterns with Bootstrap. The style sheets are even written using SASS, native to default Rails apps, making for easy integration. Somebody has done that work and published it as Ruby gem materialize-sass, so all I had to do was add a single line to use Materialize in my app.

Of course I still had to put in the effort to revise all the view files in my web app to pick up Materialize styling and features. That took a few days, and the reward for this effort is a practice web app which no longer look so amateurish.

The Cost for Security

In the seemingly never-ending bad news of security breaches, a recurring theme is “they knew how to prevent this, but they didn’t.” Usually in the form of editorializing condemning people as penny-pinching misers caring more about their operating cost than the customer.

The accusations may or may not be true, it’s hard to tell without the other side of the story. What’s unarguably true is that security has some cost. Performing encryption obviously takes more work than not doing any! But how expensive is that cost? Reports range wildly anywhere from less than 5% to over 50%, and it likely depends on the specific situations involved as well.

I really had no idea of the cost until I stumbled across the topic in the course of my own Rails self-education project.

I had designed my Rails project with an eye towards security. The Google ID login token is validated against Google certificates, and the resulting ID is salted and hashed for storage. The code for this added security were deceptively minor, as they triggered huge amounts of work behind the scenes!

I started on this investigation because I noticed my Rails test suite ran quite slowly. Running the test suite for the Rails Tutorial sample app, the test framework ran through ~120 assertions per second. My own project test suite ran at a snail’s pace of ~12 assertions/second, 10% of the speed. What’s slowing things down so much? A few hours of experimentation and investigation pointed the finger at the encryption measures.

Obviously security is good for the production environment and should not be altered. However, for the purposes of development & test, I could weaken them because there would be no actual user data to protect. After I made a change to bypass some code and reducing complexity in others, my test suite speed rose to the expected >100 assertions/sec.

Granted, this is only an amateur at work and I’m probably making other mistakes doing security inefficiently. But as a lesson to experience “Security Has A Cost” firsthand it is eye-opening to find a 1000% performance penalty.

For a small practice exercise app like mine, where I only expect a handful of users, this is not a problem. But for a high-traffic site, having to pay ten times the cost would be the difference between making or breaking a business.

While I still don’t agree with the decisions that lead up to security breaches, at least now I have a better idea of the other side of the story.

Protecting User Identity

google-sign-inRecently, web site security breaches have been a frequent topic of mainstream news. The technology is evolving but this chapter of technology has quite some ways to go yet. Learning web frameworks gives me an opportunity to understand the mechanics from web site developer’s perspective.

For my project I decided to use Google Identity platform and let Google engineers take care of identification and authentication. By configuring the Google service to retrieve only basic information, my site never sees the vast majority of personally identifiable information. It never sees the password, name, e-mail address, etc.

All my site ever receives is a string, the Google ID. My site uses it to identify an user account. With the security adage of “what I don’t know, I can’t spill” I thought this was a pretty good setup: The only thing I know is the Google ID, I can’t spill anything else.

Which led to the next question: what’s the worst that can happen with the ID?

I had thought the ID is something Google generated for my web site. More specifically my site’s Client ID. I no longer believe so. A little experimentation (aided by a change in Client ID for the security issue previously documented) led me to now believe it’s possible the Google ID is global across all Google services.

This means if a hacker manages to get a copy of my site’s database of Google ID, they can cross-reference to databases of other compromised web sites. Potentially assembling a larger picture out of small pieces of info.

While I can’t stop using Google ID (I have to have something to identify an user) I can make it more difficult for a hacker to cross-reference my database. I’ve just committed a change to hash the ID before it is stored in the database. Salted with a value that is unique per deployed instance of the app.

Now for a hacker to penetrate the identity of my user, they must do all of the following:

  1. Obtain a copy of the database.
  2. Obtain the hashing salt used by the specific instance of the app which generated that database.
  3. Already have the user’s Google ID, since they won’t get the original ID out of my database of hashed values.

None of which are impossible, but certainly a lot more effort than it would have otherwise taken.

I think this is a worthwhile addition.

Adventures in Server-Side Authentication

google-sign-inThe latest chapter comes courtesy of the Google Identity Platform. For my next Rails app project, I decided to venture away from the user password authentication engine outlined in the Hartl Ruby on Rails Tutorial sample app. I had seen the “Sign in with Google” button on several web sites (like Codecademy) and decided to see it from the other side: Users for my next Rails project will sign in with Google!

The client-side code was straightforward following directions in the Google documentation. The HTML is literally copy-and-paste, the JavaScript needed some reworking to translate into CoffeeScript for the standard Rails asset pipeline but wasn’t terribly hard.

The server side was less straightforward.

I started with the guide Authenticate with a Backend Server which had links to the Google API Client Library for (almost all) of the server side technologies including Ruby. The guide page itself included examples on using the client library to validate the ID token in Java, Node.JS, PHP, and Python. The lack of Ruby example would prove problematic because each flavor of the client library seems to have different conventions and use different names for the functionality.

Java library has a dedicated GoogleIdTokenVerifier class for the purpose. Node.JS library has a GoogleAuth.OAuth2 class with a verifyIdToken method. PHP has a Google_Client class with a verifyIdToken method. And to round out the set, Python library has oauth2client.verify_id_token.

Different, but they’re all in a similar vein of “verify”, “id”, and “token” so I searched the Ruby Google API client library documentation for those keywords in the name. After a few fruitless hours I concluded what I wanted wasn’t there.

Where to next? I went to the library’s Github page for clues. I had to wade through a lot of material irrelevant to the immediate task because the large library covers the entire surface of Google services.

I thought I had hit the jackpot when I found reference to the Google Auth Library for Ruby. It’s intended to handle all authentication work for the big client library, with the target completion date of Q2 2015. (Hmm…) Surely it would be here!

It was not.

After too many wrong turns, I looked at Signet in detail. It has a OAuth2::Client class, which sounded very similar to the other libraries, but it had no “verify” method so every time I see a reference to Signet I keep deciding to look elsewhere. Once I decided to read into the details of Signet::OAuth2::Client, I finally figured out that it had a decoded_id_token method that can optionally verify the token.

So it had the verification feature but the keyword “verify” itself wasn’t in the name, throwing off my search multiple times.

Gah.

Nothing to do now but to take some deep breaths, clear out the pent-up frustration, and keep on working…

Simple Online Digital Photo Frame

The CarrierWave Playground project was created for experimentation with image upload. As intended, it helped me learn things about CarrierWave such as creating versions of the image scaled to different resolutions and extracting EXIF image metadata.

Obviously the image has to be displayed to prove that the upload was successful. I hadn’t intended to spend much time on the display side of things, but I started playing with the HTML and kept going. Logic was added for the browser to report its window size so the optimal image could be sent and scaled to fit. I had a button to reload the page, and it was fairly simple to change it from “reload the current page” to “navigate to another page”. Adding a JavaScript timer to execute this navigation… and voila! I had myself a rudimentary digital photo frame web app that loads and displays image in a sequence.

It’s fun but fairly crude. Brainstorming the possibilities, I imagine the following stages of sophistication:

Stage 1 – Basic: Where I am now, simple JavaScript that performs page navigation on a timer.

Problem: page blinks and abruptly shifts as new page is loaded. To avoid the abrupt shift, we have to eliminate the page switch.

Stage 2 – Add AJAX: Instead of a page navigation, perform a XMLHttpRequest to the server asking for information on the next image. Load the image in the background, and once complete, perform a smooth transition (fade out/fade in/etc.) from one image to the next.

Problem: Visual experience is at the mercy of the web browser, which probably has an address bar and other UI on screen. Also, the user’s screen will quickly go dark due to power saving features. To reliably solve both, I will need app-level access.

Stage 3 – Vendor-specific wrapper: Every OS platform has a way to allow web site authors an express lane into the app world. Microsoft offers the Windows App Studio. Apple has iOS web applications. Google has Android Web Apps.

Unknown: The JavaScript timer is a polling model, do we gain anything by moving to a server-push model? If so, that means…

Stage 4 – WebSocket: Photo updates are triggered by the server. Since I’m on Rails, the most obvious answer is to do this via WebSockets using Action Cable.

Looking at the list, I think I can tackle Stage 2 pretty soon if not immediately.

Stages 3 and 4 are more advanced and I’ll hold off for later.

EXIF fun with CarrierWave uploader

To play with the CarrierWave uploader gem I created a new Rails project just for the purpose of experimentation. I had thought about doing this as part of the Hartl Rails Tutorial sample app but ultimately decided to keep things as bare-bones as I can.

When trying to understand a new system, a debugger is a developer’s best friend. Part of this exercise is to get my feet wet using a debugger to poke around a running Rails app. The Hartl Rails Tutorial text introduced the byebug gem but only minimally covered usage. The official Rails Guides had more information which helped me get going, in addition to various users writing up their own cheat sheets.

I decided to dig into image metadata. Basic information such as width and height were made available as img[:width] and img[:height] but where are the others? With the help of byebug I found that they were available in the img.data hash. Most of the photography-specific EXIF metadata are in there as well, though somebody interested only in that subset can access it via the img.exif hash.

As an exercise I decided to try to pull out the original date. Time stamp on digital photography files have always been a headache. Most computer OS track “Created Date” and “Modified Date” but they are relative to the computer and not reliable for photo organization purposes. Photo editing introduces another twist: if an image is created from a photograph, the time stamp would be the day the edit operation was made and not when the original photo was taken.

Which is how I ended up looking at EXIF “DateTime”, “DateTimeOriginal”, and “DateTimeDigitized” to take the earliest date of the three (when present).  Then I ran into another can of worms: time zones. The EXIF time stamp have no time zone information, but the Ruby DateTime object type does. Now my time stamps are interpreted as UTC when it isn’t. Since EXIF doesn’t carry time zone data (that I can find) I decided to leave that problem to be tackled another day.

Behavior Driven Development

cucumberlogoMy new concept of the day: Behavior Driven Development. As this beginner understands the concept, the ideal is that the plain-English customer demands on the software is formalized just enough to make it a part of automated testing. In hindsight, a perfectly logical extension of Test-Driven Development concepts, which started as QA demands on software treated as the horse instead of the cart. I think BDD can be a pretty fantastic concept, but I haven’t seen enough to decide if I like the current state of the art in execution.

I stumbled into this entirely by accident. As a follow-up to the Rails Tutorial project, I took a closer look at one corner of the sample app. The image upload feature of the sample app used a gem called carrierwave uploader to do most of the work. In the context of the tutorial, CarrierWave was a magic black box that was pulled in and used without much explanation. I wanted to better understand the features (and limitations) of CarrierWave for use (or not) in my own projects.

As is typical of open-source projects, the documentation that exists is relatively thin and occasionally backed by the disclaimer “for more details, see source code.” I prefer better documentation up front but I thought: whatever, I’m a programmer, I can handle code spelunking. It should be a good exercise anyway.

Since I was exploring, I decided to poke my head into the first (alphabetically sorted) directory : /features/. And I was immediately puzzled by the files I read. The language is too formal to be conversational English for human beings, but too informal to be a programming language as I knew one. Some amount of Google-assisted research led me to the web site for Cucumber, the BDD tool used by the developers of CarrierWave.

That journey was fun, illuminating, and I haven’t even learned anything about CarrierWave itself yet!

Dipping toes in AWS via Rails Tutorial Sample App

aws_logoAmazon Web Services is a big, big ball of yarn. For somebody just getting started, the list of AWS products is quite intimidating. It’s not any fault of Amazon, it’s just the nature of building out such a comprehensive system. Fortunately, Amazon is not blind to the fact people can get overwhelmed and put admirable effort into a gentle introduction via their Getting Started resources: a series of (relatively) simple guided tours through select parts of the AWS domain.

At the end of it all, though, a developer has to roll up their sleeves and dive in. The question then is: where? In previous times, I couldn’t make up my mind and got stuck. This time around, I have a starting point: Michael Hartl’s Ruby on Rails Tutorial sample app, which wants to store images on Amazon S3 (Simple Storage Service).

Let’s make it happen.

One option is to blaze the simplest, most direct path to get rolling, but I resisted. The example I found on stackoverflow.com granted the rails app full access to storage with my AWS root credentials. Functionally speaking that would work, but that is a very bad idea from a security practices standpoint.

So I took a detour through Amazon IAM (Identity and Access Management). I wanted to learn how to do a properly scoped security access scheme for the Rails sample app, rather than giving it the Golden Key to the entire kingdom. Unfortunately, since IAM is used to manage access to all AWS properties, it is a pretty big ball of yarn itself.

Eventually I found my on-ramp to AWS: A section in the S3 documentation that discussed access control via IAM. Since I control the rails app and my own AWS account, I was able to skip a lot of the cross-account management for this first learning pass, boiling it down to the basics of what I can do for myself to implement IAM best practices on S3 access for my Rails app.

After a few bumps in the exploration effort, here’s what I ended up with.


Root account: This has access to everything, so we want to use this account as little as possible to minimize risk of compromising this account. Login to this account just long enough to activate multi-factor authentication and create an IAM user account with “AdministratorAccess” privileges. Log out of the management console as root, log back in under the new admin account to do everything else.

Admin account: This account is still very powerful so it is still worth protecting. But if it should be compromised, it can at least be shut down without closing the whole Amazon account. (If root is compromised, all bets are off.) Use this account to set up the remaining items.

Storage bucket: While logged in as the admin account, go to the S3 service dashboard and create a new storage bucket.

Access policy: Go to the IAM dashboard and create a new S3 access policy. The “resource” of the policy is the storage bucket we just created. The “action” we allow are the minimum set needed for the rails sample app and no more.

  1. PutObject – this permission allows the rails app to upload the image file itself.
  2. PutObjectAcl – this permission allows the rails app to change the access permission on the image object, make the image publicly visible to the world. This is required for use as the source field of an HTML <img> tag in the rails app.
  3. DeleteObject – when a micropost is deleted, the app needs this permission so the corresponding image can be deleted as well.

Access group: From the IAM dashboard, create a new access group. Under the “Permissions” list of the group, attach the access policy we just created. Now any account which is a member of the group has enough access the storage bucket to run the rails sample app.

User: From the IAM dashboard, create a new user account to be used by the rails app. Add this newly user to the access group we just created, so it is a part of the group and can use the access policy we created. (And no more.)

This new user, which we granted only a low level of access, will not need a password since we’ll never log in to Amazon management console with it. But we will need to generate an app access key and secret key.

Once all of the above are done, we have everything we need to put into Heroku for the Rails Tutorial sample app. A S3 storage bucket name, plus the access and secret key of the low level user account we created to access that S3 storage bucket.


While this is far more complex than the stackoverflow.com answer, it is more secure. Plus a good exercise to learn the major bits and pieces of an AWS access control system.

The above steps will ensure that, if the Rails sample app should be compromised in any way, the hacker has only the permissions we granted to the app and no more. While the hacker can put new images on the S3 bucket and make them visible, or delete existing images, but they can’t do anything else in that S3 bucket.

And most importantly, the hacker has no access to any other part of my AWS account.

Rails Tutorial (Take 2)

RailsTutorial-cover-webWith all the fun and excitement around 3D printing, I’ve let my Ruby on Rails education lapse. I want to dive back in, but it’s been long enough that I felt I needed a review. Also, during my time away, the Ruby on Rails team released version 5, and Michael Hartl’s Ruby on Rails Tutorial was updated accordingly.

Independent of the Rails 5 updates, it was well worth my time to go through the book again. On second run, I understood some things that didn’t make sense before. It was also good to look at the first do-nothing “hello app” and the second automated-scaffold “toy app” with a little more Rails knowledge under my belt. The book is structured so the beginner reader didn’t have to understand the mechanics of the hello or toy apps, but readers with a bit of understanding will get something out of it.

The release notes for the update mentioned that a few sections were rearranged for better pacing and structure, and added more exercises for readers to check their progress. Both are incremental improvements that I appreciated but neither were especially earth-shattering.

Action Cable, one of the big signature feature of Rails 5, was not rolled into the book. Hartl is handling that in a separate tutorial Learn Enough Action Cable to be Dangerous which I will go through at some point in the near future.

Towards the end of the book, Hartl introduced an optional advanced concept: using Amazon Web Services to store user image uploads. I skipped that section the first time through, and decided to dive into it this time.

I quickly found myself in a deep rabbit hole. Amazon Web Services has many moving parts designed for a wide range of audiences and it’s a challenge to get started without being overwhelmed.

Which is where I am now. Lots more exploration ahead!

“Ruby on Rails Tutorial” notes

RailsTutorial-cover-webTowards the end of the Getting Started with Rails guide, there was a link to the Ruby on Rails Tutorial. I had missed it the first time I went through the Getting Started guide, but when I reviewed the guide a second time (things made a lot more sense) I noticed and decided to check it out.

I’m very glad that I did!

For the most part, this book (available as paper edition, but the author had made it freely readable online on the web site) was exactly what I had hoped to find for Ruby on Rails. The book went through the process of making a Rails app three times, in exactly the progression I wanted:

First pass: A simple “hello world” that does nothing much but lets the student experience all the standard overhead around creating and deploying a Rails app. It’s barely a Rails lesson at all: it’s really a lesson for learning the surrounding infrastructure before digging into the meat of learning Rails.

Second pass: A simple “toy app” that does a lot… but the student is rushed through without understanding what’s going on behind the scene. It’s really a demonstration of what’s possible via Rails helpers & scaffolding and less about learning Rails. It reminds me of what the Codecademy Ruby on Rails “class” was like. A lot of incomprehensible fancy flash. However, unlike Codecademy which left me asking “now what?” Rails Tutorial follows up.

Third pass: Over 80% of the book is spent building the “sample app.” Starting from a site that can serve a few static pages and grows, bit by bit, into a mini clone of Twitter. It had creation and maintenance of user accounts, authentication, posting 140-character messages, following & un-following users, all the core bits we associate with Twitter. (Which, the author asserted, was also originally built using Ruby on Rails.)

The Codecademy Rails class left me confused and feeling like I’ve wasted my time. (About a day.)

The Rails Guides left me with a basic level of comprehension of what goes on in a Rails app. My time (About half a week) is well spent, but I didn’t feel like I could build anything on my own yet.

After the Ruby on Rails Tutorial (which took me over a week) I feel like I have all the basic tools I need to start playing in the Rails playground. I feel like I have an idea how to get started, how to experiment, understand what the experiment does behind the scenes, and debug whatever goes wrong while I experiment.

And with that, it’s time to practice using my new tools: Let’s build something!

Codecademy “Learn Sass” notes

SasslogoWhile learning Ruby on Rails, one of the things I put on my “look into this later” list was Sass. I knew it was related to CSS but didn’t know the details, I just noticed when the Rails generator created a controller, it created a .scss file under the stylesheets directory.

So when I received email from Codecademy notifying me that they have a new class on Sass… the “look into this later” became “let’s look into it now”.

Unlike Ruby on Rails, Sass is not a huge complicated system. It solves a fairly specific set of problems typical of CSS growing unwieldy as it grows with a project. It introduces some very nice concepts to keep CSS information organized. After banging my head on lots of walls with Ruby on Rails, it is refreshing to tackle a smaller-scope project and be able to understand what’s going on. The Codecademy format is well suited to teach a smaller scoped concept like Sass.

I was also mildly amused to learn that Sass is apparently written in Ruby. I don’t think it particularly matters what the implementation was, but it’s amusing to me to see Ruby applied in an entirely different way from Rails. The bonus is that, if I should try to debug or extend Sass myself, I wouldn’t be starting from scratch looking over its source code.

Being a fresh course, the Codecademy class had a few minor problems that still need to get ironed out. The flashcard example was supposed to flip on mouse hover… it never did anything for me. Too bad, because I think the effect would have been interesting.

I haven’t gotten far enough with Rails to think about making my web app pretty, but when I do, I know how to keep my style sheets manageable with Sass.

Minor Derailment Due To Infrastructure

One of the reasons I put Node.js education on hold and started with Ruby on Rails is because of my existing account at Dreamhost. Their least expensive shared hosting plan does not support Node.js applications. It does support Ruby on Rails, PHP, and a few others, so I started learning about Ruby on Rails instead.

The officially supported version of Ruby (and associated Ruby on Rails) is very old, but their customer support wiki assured me it could be updated via RVM. However, it wasn’t until I paid money and got into the control panel did I learn RVM is not supported on their shared hosting plan.

RVM Requires VPS

At this point I feel like the victim of a bait-and-switch…

So if I want to work with a non-ancient version of Ruby on Rails (and I do) I must upgrade to a different plan. Their dedicated server option is out of the question due to expense, so it’s a choice between their managed Virtual Private Server option or a raw virtual machine via DreamCompute.

In either case, I didn’t need to pause my study of Node.js because it’d work on these more expensive plans. Still, Ruby is a much more pleasant language than JavaScript. And Rails is a much better integrated stack than the free-wheeling Node.js. So it wasn’t all loss.

Before I plunk down more money, though, I think I should look into PHP. It was one of the alternatives to Ruby when I learned NodeJS wasn’t supported on Dreamhost shared hosting. It is the server-side technology available to Dreamhost shared hosting, fully managed and kept up to date. Or at least I think it is! Maybe I’ll learn differently as I get into it… again.

Dreamhost offers a 97-day satisfaction guarantee. I can probably use that to get off of shared hosting and move on to VPS. It’s also a chance find out if their customer service department is any good.

UPDATE 1: Dreamhost allowed me to cancel my hosting plan and refunded my money, zero fuss. Two clicks on the web control panel (plus two more to confirm) and the refund was done. This is pretty fantastic.

UPDATE 2: I found Heroku, a PaaS service that caters to developers working in Rails and other related web technologies. (It started with Ruby on Rails then expanded from there.) For trial and experimentation purposes, there is a free tier of Heroku I can use, and I shall.

RailGuides on Active Record

rails_guides_logo

There’s not a whole lot to say about the individual courses, so I’m going to cram a few into a single post here.

  • Active Record Basics: A good overview of Active Record, expanding upon the concepts introduced during the Getting Started guide. As a Rails novice, the conventions around naming and schema are fascinating. The goal is clearly “do what the user meant” and the magic sure looks impressive up front. But I know from experience, when the magic fails and the user has to deal with the raw guts, it might be unpleasant.
  • Active Record Migrations: This is where I started feeling like I could use more guidance. It feels like the intended audience is already well versed in database concepts… which I am not.
  • Active Record Validations: This one feels like a fairly straightforward view of doing data checks using Ruby code instead of SQL. It even goes into some detail on when you’d want to use Ruby vs. directly in the database. (Not that I necessarily understood all of it…)
  • Active Record Callbacks: Life cycle of an Active Record and when/where I can place some code of my own to look at the latest data. I don’t think this will really sink in until I see a situation where I need it.
  • Active Record Associations: I started getting in over my head here. I think I would do better if I knew more about designing database schema, but I did not. As a result the associations feel like a toolbox full of tools I don’t know how to use on problems.
  • Active Record Query Interface: If somebody can think in SQL, this section will explain how Rails features are mapped to SQL queries behind the scenes and vice versa. Sadly I’m too rusty in SQL for this section to be particularly enlightening.

For me, the general theme here is: Good, except the parts that expect me to have more SQL database knowledge than I actually do. I plan to come back and review this information later, but between now and then, I think it’d be a good idea to brush up on my SQL.

RailsGuides “Testing Rails Applications” notes

rails_guides_logo

In professional software development, the adage is “If it hasn’t been tested, it doesn’t work.” It’s easy to write some code that I believe does what I want… it might even pass a few smoke tests. But if it hasn’t been examined with some rigor, it is worthless. Time and time again test suites proved their value by exposing problems in my code. With their help I knew what I need to fix to make things better.

Yet with all this importance, testing techniques and methodologies are rarely covered – or even mentioned – in most curriculum on software development. This is why I was most surprised to find the section Testing Rails Applications on the list of RailsGuides.

I’m still too much of a Rails beginner to understand all of the information in the lesson, so I would definitely have to come back later, but it is enough for me to get a rough idea of the capabilities of the built-in testing framework.

I was most amused to see that the built-in creation scripts for Rails models and controllers would create the test scripts at the same time it created the code. A not-so-subtle reminder for the developer to go and write some tests. At this point, the source code files and the test files are both sitting empty and ready to go. We could start writing the source code – but we could have just as easily started writing the test files first.

Write the test, see it fail, write the code, see it pass.

At least that’s the theory of test-driven development. I don’t know if I’ll approach Rails development in this manner, but I do appreciate how Rails removes so much of the barriers to entry.

RailsGuides “Securing Rails Applications” notes

rails_guides_logo

As I enter the world of web development, I’m very wary of the security pitfalls of the domain. It is a completely different set of security threats than what I used to worry about. Different attack vectors that need to be defended against or mitigated with different techniques.

I had known about the Open Web Application Security Project (OWASP) but I can’t say I’ve reached proficiency understanding all the concepts there. At this point I can articulate most of the concepts listed in the OWASP Top 10 list. If I come across a description of an attack using one of these top 10 techniques, I can follow along with the description.

But that is far far short of the skill level where I can spot the security issues ahead of time. That is yet to come. With expectations set suitably low, I went through the Securing Rails Applications RailGuide to see how much I can understand. And surprisingly… quite a lot! Whoever wrote this guide was able to explain a lot of these issues in a way I can understand. I really appreciate the effort they put into breaking the problems down.

With every exploit, the guide also describes some mitigation for Rails applications. Not knowing a whole lot about Rails just yet, most of the mitigation descriptions made little sense. So while I understood more than I thought I would, I’d still have to come back again.

Right now I have no confidence that I can tell a secure Rails app from an insecure one. There’s a whole lot of very clever people trying to find ways to break security boundaries. Whenever I read about an exploit, I usually end up shaking my head “I never would have thought to try that.”

Since there’s no way to guard against a problem you never thought of, I need to build up my web programming toolbox. I want to get from “I never would have thought to try that” to “ah, that’s a clever thing to try” to “no problem, I’m pretty sure I’ve taken care of it.”

One step at a time.

RailsGuides “Getting Started with Rails” notes

rails_guides_logo

It is my opinion that RailGuides’ Getting Started with Rails is a far superior educational resource than the Codecademy class on Rails which I did not care for at all.

The only thing I can say in favor of the Codecademy edition is the completely browser-based Codecademy learning environment. To run through the Codecademy tutorial mystery show, one only needs a browser. RailGuide has no patience to set up a virtual machine for you. It wants the reader to set up their own fully functional Ruby environment to follow along. (Don’t worry, instructions are right up front in Section 1.) If people are just surveying the technology, this may be more than they are willing to do. But those who are serious about getting their hands dirty will want it anyway, so I didn’t see that as a barrier.

Getting Started with Rails does a far better job of describing what Rails is, what it does, and the components that the students will be activating in the lesson. It explained the directory structure. It explained the relationship of the view and the model and the controller. It explained how the database relates to the model. On and on, tons of info I failed to get out of Codecademy.

The best part was when the class went into partial forms. (Codecademy didn’t cover the topic at all.) First the student did it the hard way, then the student is instructed on how to clean up after themselves and simplify the structure with partials. See the original – then work the magic yourself – makes for superior comprehension.

Ruby on Rails is a big complex machine and there’s still lots to learn. Like routing… the link_to routes are still magic to me. But I feel like I have a solid foundation now, which I didn’t feel before.

Onward to more Rails adventures…

Learn Ruby with the Neo Ruby Koans

ensoThe Ruby language site lists some resources for beginners in their Documentation section. Most of them followed the usual pattern of online language courses, but the Ruby Koans stood out. It is a language lesson by the way of test-driven development. The entire course is in the form of a single Ruby program full of test cases (280-ish when I downloaded it) that all fail. The job of the Ruby student is to look at the test case, understand what the test requires, modify the test case so that it succeeds, and proceed to the next one.

The very first test case is simple – true versus false. Then it progressively built up from there. Data types, flow control, object hierarchy, the works. While this covers much of the same ground as the Codecademy course I took a few days ago, the presentation and the format kept me engaged in a way the Codecademy course did not.

One reason was that it’s possible to “fast forward” through sections I understood: The test cases are all there in Ruby source files. So once I understood the concept covered by one test case, I can continue editing the similar test cases and have them all passing in one batch instead of one case at a time. In contrast to something like Codecademy where, even if I understood the concept, I still had click through the pages one at a time.

Bonus: after I finish the lessons, I have a bunch of Ruby files exercising various Ruby concepts that I can go back and look at for reference. It is much faster to scan through a Ruby file than it is to click through a Codecademy lesson.

This Ruby Koans approach to learning Ruby might not work with everybody, but I loved it.

RVM makes Ruby installation easy(*)

logo

(*) As long as you are running some flavor of Unix.

Ruby has a reputation for being difficult to set up. Looking at the setup documentation, I can see where that reputation came from. I suspect most of the reputation I heard came from Windows users, since that’s the camp I’ve historically been in. Windows users aren’t used to being treated as afterthoughts… and the Ruby community certainly does treat Windows as a second-class citizen. Most information applied to various flavors of Unix. Random aside: This surprisingly included the very-remotely-Unix-based Mac OS X. Mac instructions are more about ‘updating’ and I eventually figured out that recent versions of Mac OS X included Ruby. (An older version recognized to be stable but out of date.)

Back to Windows: Everything I found can be summed up as “Eh… look at this forum post, some people had good luck with XYZ. But you’re on your own, pal.”

After reviewing my options, I decided my first steps to the Ruby world would be:

  1. Ignore all the Windows hacks instructions.
  2. On my Windows development computer, install Ubuntu in a Hyper-V Virtual Machine.
  3. Inside the VM, follow the directions for installing Ruby on Ubuntu via RVM

RVM (Ruby Version Manager) is an utility some Ruby users wrote to help them keep the various Ruby versions straight. The fact this even exists and considered necessary is a little disquieting. Ruby users have to use something like RVM to switch versions around to match the version of whatever they need to get done that day. This implies that backwards compatibility is not exactly a strength of Ruby. (Possibly not even a design goal…)

I spent most of my professional career to date worrying about backwards compatibility day and night. This is a very different world. I’m not sure I’ll like it here, but I’m sure going to give it a try.

 

Codecademy “Learn Ruby on Rails” notes

Codecademy RailsThis class rushes through the basics of setting up a Rails app without explaining the bulk of what happened. This is not itself a bad thing: it let me see that Rails has a large surface area of machinery, pre-built components that can be put to work quickly.

But the majority of the course is of the “type this and look at the results” without much explanation of what I just typed and why. Example: After writing a few lines of Ruby code, the student is instructed to go into the command prompt and type “rake db:migrate” followed by “rake db:seed” before instructed to marvel at the result of the magic.

What did that do? The class didn’t really say beyond “made database”. Afterwards I went back and dig into the documentation to come up with a guess at what’s going on:

The lines of code turned out to be a way to define schema for a database table. After the schema is updated, the table itself is migrated from the previous schema to the new schema. In this case there is no existing table, so ‘migrate’ creates a new empty one. Then “db:seed” inserts some information pre-generated by the Codecademy course author into the just-created database so it is not empty.

And “rake”, which I had inferred to be some kind of database tool, is actually a general task running tool like “make” for C. I got the wrong impression since all I saw were database tasks.

That’s one example, there were many others. With this lack of explanation I’m sure I have quite a few misconceived notions on how Rails apps are built. Heck, what I described above with ‘db:migrate’ etc. might be wrong! I’ll learn my errors in due course.

If it was titled “Interactive demo of Ruby on Rails” I would be satisfied with what I got, but I don’t think it deserves the title “Learn Ruby on Rails” when actual learning has been left as an exercise for the student.

Codecademy “Learn Ruby” notes

Upside: Despite being the last in the list of language skill courses, the Codecademy “Learn Ruby” course does not assume the student knows anything about programming. It will start at the very beginning with variables, functions, flow control, etc.

Downside: If you already know basic programming concepts, the first few sections will be a complete bore as it teaches the concept of variables, function, flow control, etc. The only reason to put up with any of it is to learn the Ruby syntax for these basic concepts.

Fortunately, the class doesn’t take terribly long before getting into the interesting stuff. Like how Ruby’s basic data types have a lot more tools attached to them than other languages I’ve seen. All kinds of ways to traverse an array. The crazy number of things built in for various string manipulation. Things that, in other languages, a programmer would have to get from utility libraries outside of the language base.

That said, I’m not sure I see how these differences explain the enthusiasm I read from some Ruby champions. At the basic level covered in the Codecademy class, it doesn’t seem significantly different from any of the other object-oriented programming languages out there. Yes, it has a lot of built-in capabilities for common operations, but is that really enough to get people excited?

I haven’t seen the debugging facilities (or lack thereof) for Ruby. I’m also wary of the reputation Ruby has for being difficult to get up and running on a computer. Inside the Codecademy learning environment, it’s already set up. Getting it up and running on your own has been repeatedly warned as a nontrivial process.

No matter, I wasn’t learning Ruby for the sake of learning a new language. I was learning it as a foundation to build on learning a non-basic-library: Ruby on Rails.

That’s next.