Detour: Brief Tips for Programming Interviews

I have had a few run-ins with programming-interview questions as of late, and although the questions are normally straightforward and familiar, my nervousness makes them far more menacing than they are. As a result, my responses to them are, well, less than ideal (they’re still solutions at least!).

Failing to make a good impression on an employer is not a fun situation to be in; nonetheless, it is a valuable educational opportunity for me and other budding programmers to grow and learn from. Here are a few tips that I think are helpful for both myself and others:

Prepare. Yep, even though it sounds silly, I still said it. Here’s why: Though companies want to see your projects – and you definitely should have one or a few – you should still take the time to refresh and broaden your theoretical knowledge and overall problem-solving skills. It’s easy for such knowledge and skills to fall by the wayside when there is so much else to do and to use in software development (like all the damn frameworks and libraries 🙂 ). There are many ways to give your mind a workout in this field, but definitely challenge yourself on occasion with intricate, discrete problems in your favorite language(s). You will improve if you do so, becoming both a better programmer and a better interviewee.

After the interviewers present the problem to you, pretend that they aren’t there. Really, they aren’t there. Easier said than done, but if you pull it off, you will be a lot less tense and a lot more focused. Act as though the problem that the interviewer presented to you came from a book: think calmly about it, get clarification if you need it, and then get to work. In short, until you’re done with the problem, just ignore the interviewer (explain the steps you are taking if they ask you to, of course, but in that case, try to pretend you’re talking to yourself).

Show enthusiasm. This is pretty simple to do, but it’s easy not to do it when you are anxious. Don’t forget why you’re there, and don’t forget why you program in the first place.

I hope these tips help you out during your next interview for a tech job, and if you’re an interviewer, I hope these tips help you communicate with potential employees and conduct better interviews.

Feel free to comment and add to this list. Thanks for reading!

A Simple File Input Directive with Angular

If you want to upload an image quickly, have Angular on hand, but are a little wary of diving into Angular directives, then I have some good news for you: I’ve been there, I’m still kind of there, and I have some valuable info.

We’ll follow these steps to get a simple image-uploader working:

  1. Register a new Angular directive.
  2. Bind an upload event to that directive via your browser’s file reader.
  3. Prepare the backend to handle the upload event.

Register a New Directive

I have to admit that creating a new Angular directive was a subject I avoided for a long time, but now I have no idea why I did: Angular directives are amazing! They let their users do all kinds of awesome and weird things. But for our purposes, we’re going to keep it pretty simple.

All we need is a directive that behaves like an impatient file-input button, but we also want the user to be able to see the uploaded image. So the HTML will look something like this:

<input type=”file” image-upload>
<img ng-src={{imageData}}>

So let’s make the code above actually mean something:

angular.module('myAppDirectives', []).directive('imageUpload', ['$http', function($http) {
  return function(scope, element, attr) {
    element.on('change', function(event) {
      event.preventDefault();
      var image = element[0].files[0];
    });
  };
}]);

We’re just defining what that image-upload attribute does – and all it does is bind a particular event to whatever element the image-upload attribute is attached to. Because we’re dealing with a file-input button, we can access the uploaded file’s information and then specify what we want to do with it. Nice, right?

So what do we do with the file? We read it, but we want the browser, instead of the server, to do that for us. Enter the amazing file reader.

Browser File Reader

We just need to add some more code to our event in our directive. Specifically, we want the event to send a post request containing the image’s information. So let’s use the browser’s file reader:

angular.module('myAppDirectives', []).directive('imageUpload', ['$http', function($http) {
  return function(scope, element, attr) {
    element.on('change', function(event) {
      event.preventDefault();
      var image = element[0].files[0];
      reader = new FileReader();
      reader.onload = function(e) { $http.post('/image-upload', 
        {image: e.target.result}).then(function(res) {
          if (res.status === 200) {
            // do stuff, like scope.imageData = e.target.result;
          }
         })};
    });
  };
}]);

(Fortunately, the file reader is well supported across all browsers: http://caniuse.com/#feat=filereader)

Okay, so there is another event going on within our event, and that’s okay. Let’s break it down:

  1. When the file-input value changes, we start the first event.
  2. We prevent the default behavior.
  3. We create a new instance of FileReader.
  4. We bind an event to the FileReader itself, and the event will fire when the reader loads. This second event entails an http request sent to the server (you can make the on-load event do whatever you want, but I figured you’d probably want that data to get to your database; in which case, you can post to wherever you want and add whatever data you want :)).
  5. We handle the response from the server and update the image tag’s src attribute.

But we are just defining what happens on the reader’s onload event; how do we get that event to fire and get access to e.target.result? We have to call one of the reader’s methods – in this case, readAsDataURL. We pass the image variable as the argument:

angular.module('myAppDirectives', []).directive('imageUpload', ['$http', function($http) {
  return function(scope, element, attr) {
    element.on('change', function(event) {
      event.preventDefault();
      var image = element[0].files[0];
      reader = new FileReader();
      reader.onload = function(e) { $http.post('/image-upload', 
        {image: e.target.result}).then(function(res) {
          if (res.status === 200) {
            // do stuff, like scope.imageData = e.target.result;
          }
         })};
      reader.readAsDataURL(image);
    });
  };
}]);

This is why we have the e.target.result variable to access. The dataURL generated by this method turns our image into a string usable by the src attribute of the image tag, and so long as we have that string, we can produce the image.

Prepare the backend to handle the upload event

The POST request that gets fired in our directive can be modified however you see fit. You just have to make sure that the data string, e.target.result, makes it to your server (if you want to save it, that is). Because it’s only a string, you shouldn’t have much of a problem persisting it with your application’s backend – regardless of what you’re using.

Thanks for reading! And if you have any questions, please let me know – and I’ll respond and/or update the post accordingly.

Happy holidays!

Tokens, Encryptions, and Salts with Node.js – a Brief Example

There are great libraries to take care of your Node app’s login needs (such as Passport), but if you want to get some practice doing it yourself (even though the implementation is simple), then keep reading.

First, you will need a module that will generate a session id, so just install uuid via your terminal:

npm uuid --save node-rsa

You can read its documentation for more information, but here is an example of its use:

yourApp/server.js

app.post(‘/login’, function(req, res) {
 var userInfo = req.body.data;

 getUserFromDatabase(userInfo.name, function(err, user) {
   if (user && (user.password == userInfo.password)) {
     var token = uuid.v1();
     saveSessionToDatabase(token, someCallback());
   }
  });
});

Not so bad, right? After the session id is saved, your frontend can do whatever it needs to do. (I suggest setting some kind of expiration for the session token, of course.)

Now things get a bit more complicated: It’s time to protect your users’ passwords with salts and hashes.

Getting a salt is easy enough. A salt is just a random string of characters that you attach to a confidential string, such as a password, to strengthen that confidential string’s encryption. To make a salt, use a random-string generator to make a string with numbers, uppercase characters, and lowercase characters. Once you have that string – your salt – create a JavaScript file at the top of your app’s directory, store your string in a variable, and export it:

yourApp/salt.js

var salt = “your random string”;
module.exports = salt;

(To keep an open git repository safe, you can add salt.js to your .gitignore file; but if you don’t care or if what I said is otherwise irrelevant, read on.)

Now you can import your salt – again, it’s just a string – into your server file:

yourApp/server.js

var salt = require(./salt.js);

Next, you need a module for encryption and decryption. For this little tutorial/overview, let’s use node-rsa. Go back to your terminal, make sure you’re in your app’s directory, install the module:

npm install --save node-rsa

This module generates keys and decrypts them – for example:

yourApp/server.js

var nodeRSA = require(‘node-rsa’);
var key = new nodeRSA({b: 512);

This will work just fine for your user’s passwords – until you restart your server, that is. With the {b: 512} argument, nodeRSA will generate a new key every time you restart your server, so any data that was encrypted with an older key cannot be decrypted with a newer key. This means that while testing your app’s login capabilities, you won’t be able to login after restarting your node server. Not ideal.

But there’s an easy way around the problem:

yourApp/server.js

var nodeRSA = require(‘node-rsa’);
var key = new nodeRSA({b: 512);
console.log(key);

Bam: just copy the private key of that console output in your terminal and paste it into a JavaScript file, and do the same thing we did with the salt string (don’t neglect the newline characters!):

yourApp/key.js

var key = ‘-----BEGIN RSA PRIVATE KEY-----\nblahblahblah\nblahblahblah\nblahblahblah\n’;
module.exports = key;

And again, you should probably consider adding key.js to your .gitignore file, if applicable.

Next, remove the console.log statement from your server file and import your new string:

yourApp/server.js

var nodeRSA = require(‘node-rsa’);
var key = new nodeRSA();
var keyString = require(‘./key.js’);
key.loadFromPEM(keyString);

Now you are ready to start encrypting.

So how does one use all this encryption stuff? Well, whenever a user creates a password, you will first want to add the salt string to it before saving it – for example:

yourApp/server.js

app.post(‘/register’, function(req, res) {
 var userInfo = req.body.data;
 var passwordToEncrypt = userInfo.password + salt;
 // and then code to save userInfo to your database
});

Now that the salt string and the user’s password are concatenated, it’s time to encrypt the resulting string:

yourApp/server.js

app.post(‘/register’, function(req, res) {
  var userInfo = req.body.data;
  var passwordToEncrypt = userInfo.password + salt;
  var encryptedPassword = key.encrypt(passwordToEncrypt, ‘base64’);
  // and then code to save userInfo to your database
});

encryptedPassword is what you want to save to your database. And to ensure that the user can login, just modify your app’s login route to also use the key and the salt (in this case, for password comparison):

yourApp/server.js

app.post('/login', function(req, res) {
 var loginInfo = req.body.data;
 var password = loginInfo.password + salt;
 getUserFromDatabase(loginInfo.username, function(err, user) {
   if (user && (key.decrypt(user.password, 'utf8') == password)) {
     var token = uuid.v1();
     saveSessionToDatabase(token, someCallback());
   }
  });
});

And there you go. Now you have a basic encryption/decryption system in place for sensitive user data. Of course, you can add more salts and keys for all kinds of things if you want. Have fun!

And – again, as always – let me know if you have any questions. Thanks for reading!

Detour: The Fear and Taking the Plunge

This month marks a year since I made an enormous and risky career change: I left a comfy position to pursue my burgeoning passion for programming and the startup world, and I haven’t regretted doing so one bit. But does that mean all is calm?

Not at all.

The inspiring cliches about pursuing one’s passions or dreams are well known to just about everyone. So instead of talking about those, I’ll talk about the very real fear that comes with journeying into the startup world and how I am managing that fear; but I definitely wouldn’t say I’ve conquered it – not by a long shot.

Fear of failure is the fear that was with me before I took the plunge and is still with me today; it is the fear I am currently managing despite my success thus far, for which I’m grateful.

Just about everyone can relate to the fear of failure. It’s not fun to confront, and it doesn’t reside easily. But to minimize its effects, as well as get used to its company, I did or do these things:

    • Create a backup plan. This seems blatantly obvious, but it makes one’s fear of failure considerably less menacing. Good backup plans make you want to try because they make sure you have less to lose.
    • Strive to learn. The more you learn, the more confident you become, and the less frightened you will be. Also, striving to learn more and more is pleasantly intense and distracting.
    • Remember why you took the plunge. There will be days with which you will struggle, so taking the time to remember why you bothered will help you get through those difficult days. Of course, if the reason that you took the plunge becomes less and less appealing and the days become tougher and tougher, it may be time to change course and/or use the backup plan. (There’s no shame in doing that; in fact, doing that may be an incredibly wise decision.)
    • Be patient. I often find myself scared when I think that things – whether they involve learning a new skill, coming up with a project idea, or getting a job offer – aren’t happening fast enough. To calm down, I exercise as much patience as I can. Things happen as things happen, and if there is nothing I can do to make them happen more quickly, then I just move on to something else.
    • Be persistent. This is a corollary of the previous point. In the context of entrepreneurship, patience and persistence go hand and hand. Actually, now that I think about it, perhaps a healthy dose of Stoicism would help many would-be entrepreneurs. In short and oversimplified terms, control what you can and accept what you must.

These five points aren’t some secret recipe that will lead to fearlessness and guarantee success; they are just guidelines that help me deal with the challenges of working on my own (you know, the whole fear thing).

I hope any budding startup folks/entrepreneurs got some use out of this. If you have any experiences or advice you’d like to add, please feel free to share it. I don’t think I’m the only one who has discovered that overcoming the fear of failure has a lot more to do with handling it than ignoring it. 🙂

Thanks for reading!

(I’ve been extremely busy recently and haven’t had time to complete another tutorial, but I’m trying! Life is just making it difficult – in a good way.)

 

Using a Javascript File for Front End and Back End with Node.js – A Little Tip

If you have to use a Javascript document on both the front end and a Node.js back end, you can easily do so with something like this:

some_library.js

var moduleName = {
  function1: function() {},
  function2: function() {},
  function3: function() {}
};

if (typeof module === 'undefined') {
  var function1 = moduleName.function1;
  var function2 = moduleName.function2;
  var function3 = moduleName.function3;
}
else {
  module.exports = moduleName;
}

This file is now readable in both the back-end and front-end contexts. Through Node’s module.exports, you can require it in your server.js/app.js file; and when the module variable is not defined, you can access everything you specify after the if statement (except module.exports) in your front end; just include some_library.js with a script tag and you’re good to go:

server.js (or app.js)

// Bunch of other Node modules...
var moduleName = require('./path/to/some_library.js');

moduleName.function1();
// etc.

And assuming you need your library in your app’s index.html file…

index.html

<script src='./path/to/some_library.js'> function1(); </script>

I recently had to make a file like the above for another project I’m working on, so I figured other people might run into a similar situation and might need a quick example to reference. I hope it proves useful.

Let me know if you have any questions, and thanks for reading! Stay tuned for a tutorial about Node.js, Redis, and Angular.

Adding Password Reset to an Ember-Rails Application

Adding a password-reset feature to an Ember-Rails app is pretty straightforward, and it opens up many possibilities once you’re done. Before we go on, here are my implicit (and now explicit) assumptions:

  • You have a Ember-Rails application.
  • Your app uses Rails 4.
  • Your app has some kind of authentication.
  • Your app has a user model with an email attribute and the has_secure_password attribute.

If you’re all set, then let’s get going!

 

Prepping the Rails Backend

Rails’s ActionMailer is amazing, so let’s set it up (um, assuming you haven’t already). Visit your terminal and run this command:

$ rails g UserMailer

And after your mailer is created, visit your app’s mailers directory, open up user_mailer.rb, and make it look something like this:

your_app_name/app/mailers/user_mailer.rb

class UserMailer < ActionMailer::Base
  default from: "whatever@whatever.com"

  def password_reset(user)
    @user = user
    @new_password = user.password.to_s
    mail(to: @user.email, subject: 'Password Reset')
  end
end

Okay, that’s nice, but how are we supposed to use it with Ember? Well, we have to add a new route and a corresponding controller.

Go to config/routes.rb and create a new route that looks like this:

your_app_name/app/config/routes.rb

post 'password_reset' => 'password_reset#create'

So long as you have the verb post, you can name the route and the controller method and action whatever you want, but something like the above is a pretty straightforward convention.

And now we should probably make the controller that our route references, or else nothing but errors will happen. Visit your terminal again and run this command:

$ rails g controller PasswordReset

Then visit the password-reset controller and update it to something like this:

your_app_name/app/controllers/password_reset_controller

class PasswordResetController < ApplicationController
  respond_to :json

  def create
    user = User.where("username = ? OR email = ?", params[:username_or_email], params[:username_or_email]).first
    if user
      new_password = Array.new(10){[*'0'..'9', *'a'..'z', *'A'..'Z'].sample}.join
      user.update_attribute(:password, new_password)
      user.update_attribute(:password_confirmation, new_password)
      UserMailer.password_reset(user).deliver
      render json: "Password Reset. Check your inbox at #{user.email}.", status: 200
    else
      render json: "Unable to find that user. Please try again.", status: 404
    end
  end
end

This controller does these actions:

  1. Finds a user according to his/her username or email
  2. Generates a new password
  3. Updates the user’s password attributes
  4. Invokes the UserMailer class to grab the password-reset email and deliver to the user
  5. Returns some JSON text that lets the user know that his/her password has been reset (or not)

Last but not least for the Rails side, let’s create the view for the password-reset email. Go to views folder, user_mailer, and modify the view:

your_app_name/app/views/user_mailer/password_reset.text.erb

Here's your temporary password, <%= @user.name %>!

<%= @new_password %>

You can update your password after you login with this one.

Again, write whatever you want in this view, which represents the email that the user will receive after requesting a password reset (just make sure that you include the user’s new password). You’ll notice I just made the email a text file with embedded Ruby code; you’ll probably want to use a .html.erb instead for styling.

That’s it for the backend! Now all we have to do is setup a template, controller, and a route on the front end – in this case, via Ember.js.

 

Setting up the Ember Side of Things

First, we’ll have to make a resource that will represent the data we need to send to our Rails controller. So go to router.js and add this resource (or, again, something like it):

your_app_name/app/assets/javascripts/router.js

App.Router.map(function() {
  //Your other routes
  this.resource("password_reset");
});

Defining the model is next. Of course, there is no backend model for password resets; there’s only a reset controller. Nonetheless, for our Ember route, we’ll have to define a model that the Ember controller and Ember template can reference. But because we won’t be saving the password resets, we won’t use Ember’s DS.Model; instead, we’ll just use a regular Ember object:

your_app_name/app/assets/javascripts/routes/password_reset/password_reset_route.js

App.PasswordResetRoute = Ember.Route.extend({
  model: function() {
    return Ember.Object.create();
  }
});

Now let’s make the controller:

your_app_name/app/assets/javascripts/controllers/password_reset/password_reset_controller.js

App.PasswordResetController = Ember.ObjectController.extend({
  message: '',

  actions: {
    resetPassword: function() {
      var self = this;
      var data = this.getProperties('username_or_email');

      $.ajax({
        type: "POST",
        url: '/password_reset',
        data: data,
        success: function(results) {
          Ember.run(function() {
            self.set('message', results.responseText);
          });
        },
        error: function(results) {
          Ember.run(function() {
            self.set('message', results.responseText);
        });
      },
        dataType: 'json'
      });
     }
    }
  });

And finally, we have the template:

your_app_name/app/assets/javascripts/templates/password_reset.handlebars

<h2>Password Reset</h2>

<form {{action "resetPassword" on="submit"}}>

{{input type="text" value=username_or_email width=100 placeholder="Username or Email Address" id="username-or-email"}}<br>

{{#if username_or_email}}
  <button type="submit" id="reset-password">Reset Password</button>
{{else}}
  <button disabled=true>Reset Password</button>
{{/if}}

<b id="reset-message">{{message}}</b>

</form>

Again, nothing is sacred here. Change whatever you have to for your app; just make sure that the actions and attributes in the controller match those in the template. So long as the proper information gets to Rails, everything will work just fine.

As always, if you have any questions, just let me know. 🙂

Another Detour: The Bootcamp Approach to Education – a Little Review

This might seem weird, but in graduate school, I studied human-resource management; and I focused mainly on job training and adult education, both of which eventually became the topics of my thesis. I like learning about how people learn, especially when those people are adults. I call it a personal interest in professional development.

So, as someone who has studied adult-education strategies a bit and as a fairly recent grad of a web-development bootcamp, I’d like to talk about the bootcamp approach and why I think it is quite effective. (Warning: Effective does not mean “perfect.”)

What Bootcamps Do

In short, bootcamps make people good at stuff, and that is good. But why are they good at making people good at stuff?

Well, those who sign up for bootcamps usually have a strong resolve to learn what they want to learn. So part of the reason for the success of bootcamps is certainly due to having a determined population of students. But they are not the whole story: even the brightest and most determined students need guidance, regardless of whether they’re youths or adults.

Although bootcamps are innovative and new, they practice a not-at-all-new philosophy: they provide an immersive experience for students and encourage students to try, fail, and grow – again and again and again. An immersive experience helps break down adults’ many psychological barriers to learning (get a thorough overview of adults’ learning needs here). As many great educators and students know, immersion and encouragement facilitate learning, and bootcamps provide a lot of both: Students learn as many skills as they can and they do as much as they can with them. In other words, students engage in deep, purposeful practice, and although some may get more from the program than others, all who commit to the program learn plenty and push themselves according to their own limits. Well-planed repetition, challenges, and personalized support distinguish a mediocre educational program from an exceptional one, which then turns hesitant students into confident and competent professionals.

The bootcamp style of learning would work for subjects besides software development and design. For instance, imagine a 12-week-long bootcamp for technical writing. The first four weeks could be an intense study of English grammar and style; the next four, an equally intense study of the tools that technical writers use; and the last four, a period in which to complete projects. Twelve weeks may not seem like a long time, but when 40 or so hours a week are dedicated to learning, a lot can and does happen. The time constraint also focuses the efforts of the teachers, for it compels them to refine the curriculum’s content and deliver it as efficiently as possible. Of course, the teachers can alter the timeline and intensity of the curriculum as necessary, but the students will know a lot about technical writing and its tools after a few months of such learning. Educators could also develop bootcamps for skilled trades, such as welding (by the way, this is already happening, and it’s good to see).

Moreover, bootcamps don’t have to be limited to professionals looking to change careers or upgrade their skills. Consider a bootcamp for high-school dropouts who really need help, i.e., those who couldn’t pass the GED if they were to take it. Assume that the program is a six-months long and that it equips its students with foundational academic knowledge and job skills, such as reading, writing, arithmetic, communication, and science. With six months of intense, targeted education, perhaps along with internships or jobs, many positive changes could happen. A similar program could be created to help high-school students prepare for college, or even to help middle-school students prepare for high school. The many shapes that bootcamps can take is a testament to their flexibility: As long as its goals are clear, its teachers supportive, and its curriculum filled with practice opportunities, a bootcamp will likely be successful.

Are bootcamps a panacea for all academic and professional training needs? No: Education is far too complicated for a single solution. Are bootcamps worth all the attention they’re getting? Yes: They are doing things that more educational institutions need to consider and, if possible, implement.

In traditional education, everything a student does influences her final grade and thus her attitude about her ability in the subject. That one homework assignment that she found difficult could wrongly tell her that she is just no good at the subject, or needs extra help (which just sounds condescending); and then her overall grade suffers as a result. Many teachers in traditional education do drop low grades or lessen the weight of assignments that students may occasionally mishandle (such as homeworks), but neither approach is enough to encourage students. Each one only mitigates the punishment of the students’ trying. Yes, that’s exactly what such grading is: It’s not just feedback from trying; it’s often punishment for trying.

Bootcamps are all about the feedback without the punishment. Students are still evaluated on what they do, but their environment, as well as their instructors, allows and encourages them to try, fail, and grow; it does not make them get things right the first time by slapping a grade on every attempt. This intense yet supportive environment of bootcamps contributes enormously to their success.

So – That’s My Take on Bootcamps

Once more, none of the above is to say that bootcamps are perfect. Many are always refining their approaches and learning from students’ responses, and not every person finds bootcamps suitable for his preferred way of learning. But the potential of bootcamps is massive; I look forward to seeing how they evolve in the near future. Exciting times!

 

PS: The code will return soon! I have another useful Ember-Rails trick that I plan to share, as well as a Node.js one. So stay tuned and thanks for reading!

Has and Belongs to Many with Ember and Rails 4

(See Matt’s comment below for a quick updated answer; otherwise, go ahead and read. Thanks!)

Okay, because it took me a bit to figure this out, I think others might need an answer too. 🙂 This post will be brief, but I think it will help a number of people. Of course, let me know if it doesn’t.

If you don’t want to wait for the details and need an answer right away, go here, where you will learn how to alter your Ember model’s serializer and its serialize method. That is, you will learn how to change the names of your Ember models’ has-many relations to “whatever_ids” – which is required for a Rails HABTM relation.

I managed to set up a has-and-belongs-to-many relation for an Ember-Rails project, but before I go on, I must confess that I’m assuming you have a HABTM relation on the backend (not a has-many-through) and you’re using Ember’s active-model adapter. (See my earlier post if you need to get set up with Ember-Rails.)

Let’s say you have a model User, and the User has many wikis. So in Ember, your model might look like this:

App.User = DS.Model.extend({
name:  DS.attr('string'),
email: DS.attr('string'),
wikis: DS.hasMany('wiki', {async: true}),
});

And your Wiki model has many Users, so the Wiki model might look like this:

App.Wiki = DS.Model.extend({
title:  DS.attr(‘string’),
body: DS.attr(‘string’),
users: DS.hasMany(‘wiki’, {async: true})
});

So far so good, but in your server logs you’ll see that your JSON doesn’t match what Rails is expecting: that is, user_ids for Wiki’s users attribute and wiki_ids for User’s wikis attribute. You can fix the Wiki model with this code:

App.WikiSerializer = DS.ActiveModelSerializer.extend({
  serialize: function(record, options) {
    var json = {};

    record.eachAttribute(function(name) {
      json[serverAttributeName(name)] = record.get(name);
    })

    record.eachRelationship(function(name, relationship) {
      if (relationship.kind === 'hasMany' && name == ”users”) {
        json[serverHasManyName(name)] = record.get(name).mapBy('id');
      }
    });

    return json;
  }
});

function serverAttributeName(attribute) {
  return attribute.underscore().toUpperCase();
}

function serverHasManyName(name) {
  return serverAttributeName(name.singularize()) + "_ids";
}

(There are cleaner ways to do this, but this is the full package. Feel free to modify it as you see fit.)

And, of course, you will do something very, very similar with the Users model. After that, just make sure your Rails serializers for the related models embed ids and include records; and make sure the Rails controllers for the related models has “:whatever_ids => []” in the strong params. Then you’re all set to go, and life is good!

If you have any questions, don’t hesitate – you know what to do! (i.e., ask 🙂 )

 

Detour: How to Integrate Cloudinary, jQuery, and PHP (from Scratch!)

I recently started using Cloudinary for a project, and I found that many people were looking for a quick example of how to get it up and running. The awesome people at Cloudinary have several examples, but because those might be a bit time-consuming to get through, I decided to outline the steps I took to set up Cloudinary’s PHP/jQuery integration on my machine. I hope it helps!

Section 1 – Create a Cloudinary Account

I know – it’s obvious. Visit Cloudinary and register for an account. You’ll need your account information for the integration.

Section 2 – Prepare Your Machine for PHP

To configure Apache and PHP on my mac, I followed the tutorial here: https://discussions.apple.com/docs/DOC-3083

But you can also use MAMP, which is a lot easier: http://www.mamp.info/en/

Section 3 – Collect Cloudinary’s PHP Files

Visit https://github.com/cloudinary/cloudinary_php/tarball/master and get all the files in the src folder and create a directory for them. Then, in that directory, create a file called index.php (or whatever you want) and write this code:

index.php

<?php require 'Cloudinary.php';
require 'Uploader.php';
require 'Api.php';
?>

(These three files depend on the others you retrieved, so if you want to reorganize your directory(s), just keep that in mind.)

Next, create a file called configuration.php (or, again, whatever you want) and write this code to configure your php-cloudinary settings:

configuration.php

<?php \Cloudinary::config(array(
 "cloud_name" => “your_cloudinary_cloud_name”,
 "api_key" => "your_cloudinary_api_key",
 "api_secret" => "your_cloudinary_api_secret"
 ));
?>

Now just require this file in index.php:

index.php

<?php require 'Cloudinary.php';
require 'Uploader.php';
require 'Api.php';
require ‘configuration.php’;
?>

 Section 4 – All the Rest

Okay, now you have the environment and the code to get a server-side signature. Now all we have to do is take care of the client-side stuff, aka jQuery, and configure the upload settings, which are automatically configured via a few php lines.

Head back to index.php and update it like so (you can download the required javascript files at Cloudinary’s Javascript library; you can also either download jQuery or just use a link, which I have below):

index.php

<?php require 'Cloudinary.php';
require 'Uploader.php';
require 'Api.php';
require 'configuration.php';
?>

<!DOCTYPE HTML>
  <html>
    <head>
      <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js'></script>
      <script src='jquery.ui.widget.js' type='text/javascript'></script>
      <script src='jquery.iframe-transport.js' type='text/javascript'></script>
      <script src='jquery.fileupload.js' type='text/javascript'></script>
      <script src='jquery.cloudinary.js' type='text/javascript'></script>
  </head>
  
  <body>
    <?php echo cloudinary_js_config(); ?>
    <?php
      if (array_key_exists('REQUEST_SCHEME', $_SERVER)) {
        $cors_location = $_SERVER["REQUEST_SCHEME"] . "://" . $_SERVER["SERVER_NAME"] .
      dirname($_SERVER["SCRIPT_NAME"]) . "/cloudinary_cors.html";
      } else {
        $cors_location = "http://" . $_SERVER["HTTP_HOST"] . "/cloudinary_cors.html";
      }
  ?>

    <form action="uploaded.php" method="post">
      <?php echo cl_image_upload_tag('image_id', array("callback" => $cors_location)); ?>
    </form>
  </body>
</html>

(You can download the cloudinary_cors.html file here. Just save it in the same directory that you’re working in – or wherever you want.)

Now, when you load this page in your browser, you will see an file-upload button; and when you upload a file, it will go straight to your Cloudinary account!
I hope this helps those who just want to get started with Cloudinary and want to integrate it with PHP. (I was definitely one of the people who needed help!)

Let me know if you have any questions!

A Dip into Node, Express, and Angular

Node.js seems to be a pretty big deal nowadays, so not long ago I decided to check it out. And I think I’ve learned enough to give you a good introductory tutorial.

In this tutorial, we’ll keep it very simple: we’ll just make a notepad app that allows users to write notes and delete them. (Have mercy on me here – I’m still getting my feet wet!)

Section 1 – Getting Node.js

Visit http://nodejs.org/ and follow the instructions relevant to your system. Also, to get warmed up, you may want to complete the example hello-world application on the Node.js homepage.

Once you’re all set, we’ll move on to section 2. (If you wrote the hello-world application, congrats!)

Section 2 – Creating the App Directory

Create a directory called myNotePad; then add a file called package.json:

myNotePad/package.json

{
 "name": "myNotePad",
"description": "a simple note creator app",
"version": "0.0.1",
"private": true,
"dependencies": {}
}

This file specifies critical information about your application, and you absolutely must have one in any Node.js app you make. (Check out this page for additional details).

Now we’ll move on to, you know, actually creating the app!

Section 3 – Creating App.js

In your app’s directory, create a file called (you guessed it) app.js and add this code:

myNotePad/app.js

var http = require('http'),
path = require('path');

These are the first two modules we will need to design our app. Because they both come with Node.js, we don’t have to install them first; we just bring them right into our app. We will need the http module to set up our app’s server and the path module to use another directory that we’re going to make.

Next, we’ll install the Express module, the driving force of our app. In fact, what we’re really doing is creating an Express app with Node, and Express is amazing. 🙂

Section 4 – Installing and Requiring Express

Head back to myNotePad/package.json and add a dependency:

myNotePad/package.json

{
  "name": "myNotePad",
  "description": "a simple note creator app",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "express": "4.0.0"
  }
}

Visit your terminal (cd to your app’s directory, of course) and run the following command:

npm install

Now your app has a node_modules directory, which contains a directory called express, the module you just downloaded.

What’s npm? That’s node package manager, and you got it when you got Node. Because it allows you to install Node modules seamlessly, it is your best friend.

Visit myNotePad/app.js to get the Express module ready for action:

myNotePad/app.js

var http = require('http'),
path = require('path'),
express = require(‘express’),
app = express();

Thanks to Express, we now have an app object, which we will use to make stuff happen, such as setting up our server.

Section 5 – Setting up the Server

We have another change for app.js:

myNotePad/app.js

var http = require('http'),
path = require('path'),
express = require(‘express’),
app = express(),
server = http.createServer(app);

server.listen(3000);

app.get('/', function(request, response) {
  response.send(‘Hello World’);
});

Go back to your terminal and run this command:

node app.js

Then visit http://localhost:3000/and you will see hello world (my apologies if you’ve already done a version of this little exercise, but it’s good reinforcement 🙂 ). Now we know how to test drive our app!

Section 6 – Nedb

Okay, so our app is supposed to let us write notes and delete them. Well, how do we represent and save a note? Enter the nedb module, Node’s equivalent of SQLite.

Go back to myNotePad/package.json to add another dependency:

myNotePad/package.json

{
  "name": "myNotePad",
  "description": "a simple note creator app",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "express": "4.0.0",
    “nedb”: "0.10.5"
  }
}

Then back to the terminal and install it:

npm install

Now create a data directory in your app directory and add a file called notes.js:

myNotePad/data/notes.js

var path = require('path');
var Datastore = require('nedb');
var db = {
  notes: new Datastore({ filename: path.join(__dirname, 'notes.db'), autoload: true })
};

In the db variable, you can see the Nedb module in action. With it, we are creating a datastore called notes.db; and because we set the autoload option to true, the datastore will store all our notes and load them whenever we fire up the app. (Read more about Nedb – it’s pretty cool!)

So that’s all well and good, but how are we going to make this datastore actually do stuff? Let’s create another javascript object called notes and define some methods that our app will need:

myNotePad/data/notes.js

var path = require('path');
var Datastore = require('nedb');
var db = {
  notes: new Datastore({ filename: path.join(__dirname, 'notes.db'), autoload: true })
};
var notes = {
  create: function(title, body, callback) {
    db.notes.insert({ title: title, body: body }, callback);
  },
  list: function(callback) {
    db.notes.find({}).exec(callback);
  },
  remove: function(id, callback) {
    db.notes.remove({ _id: id }, callback);
  }
};

module.exports = notes;

All the methods defined in the new notes object depend on the db variable, which itself contains a datastore instance called notes. Insert, find,and remove come from the datastore instance, and we’re simply borrowing them to define our methods create, list,and remove.

That module.exports line at the bottom specifies the exported object(s) of the file when it’s required in another. Go back to myNotePad/app.js and drop in the require statement for our notes.js file:

myNotePad/app.js

var http = require('http'),
path = require('path'),
express = require(‘express’),
app = express(),

server = http.createServer(app);
server.listen(3000);

app.get('/', function(request, response) {
  response.send(‘Hello World’);
});

var notes = require('./data/notes');

And with that, app.js now has the notes object created in /data/notes.js.

Section 7 – Sockets and Views

Okay, let’s start using our notes datastore. Specifically, let’s allow users to add and remove notes from it.

The next module we will install is called socket.io, and it’s awesome. You can read more about it by visiting the link, but in short, it enables extremely fast communication between the client and the server – and that’s just what we want.

Once again, update package.json

myNotePad/package.json

{
  "name": "myNotePad",
  "description": "a simple note creator app",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "express": "4.0.0",
    “nedb”: "0.10.5",
    “socket.io”: "0.9.16"
  }
}

And install socket.io by going to your terminal and running npm install again:

npm install

Now let’s use it to handle some actions:

myNotePad/app.js

var http = require('http'),
path = require('path'),
express = require(‘express’),
app = express(),
server = http.createServer(app),
io = require('socket.io').listen(server);

server.listen(3000);

app.get('/', function(request, response) {
  response.send(‘Hello World’);
});

var notes = require('./data/notes');

io.sockets.on('connection', function (socket) {
  notes.list(function (err, documents) {
    socket.emit('list', documents);
  });
  
  socket.on('addNote', function (note) {
    notes.create(note.title, note.body, function () {
      io.sockets.emit('newNote', note);
    });
  });
  
  socket.on('removeNote', function (note) {
    notes.remove(note._id, function () {
      io.sockets.emit('deletedNote', note);
    });
  });
});

All that io.sockets stuff is telling our server how to handle incoming actions and what outgoing actions to return. For example, the notes object’s list method when a connection is established (i.e., when a user goes to the site), and then the socket sends another list method, along with the data returned from the first call to list, back to the client. The actions addNote and removeNote, work similarly: when the server receives them, the notes object’s create and remove methods are called, and then two new methods, newNote and deletedNote, get sent back to the client.

In sum, the web sockets specify actions that the server receives and the server sends and actions that the client receives and the client sends. The overall dynamic is as follows: when the client receives an action, it handles it and sends it to the server; and when the server receives the action, it handles it and then sends another action back to the client.

Okay, but the previous socket code represents the server’s behavior, so where is the client? We will create an application controller to represent the client, and with the controller we will set up some views using Angular.js, an alternative to Ember.js.

Create a folder called public and add to it a file called angular.min.js. Next, visit https://angularjs.org/ and download the legacy, minified build. Then copy and paste the code from that build into myNotePad/public/angular.min.js.

Next, in myNotePad/public/, add a file called AppController.js:

myNotePad/public/AppController.js

var socket = io.connect();

var AppController = function($scope) {
  $scope.notes = [];
  $scope.addNote = function () {
    var title = $scope.title,
    body = $scope.body;
  
    socket.emit('addNote', { title: title, body: body });

    $scope.title = '';
    $scope.body = '';
  };

  $scope.removeNote = function (note) {
    socket.emit('removeNote', note);
  };

  socket.on('list', function (documents) {
    $scope.$apply(function () {
      $scope.notes = documents;
    });
  });

  socket.on('newNote', function (note) {
    $scope.$apply(function () {
      $scope.notes.push(note);
    });
  });

  socket.on('deletedNote', function (note) {
    $scope.$apply(function () {
      var i = $scope.notes.indexOf(note);
      $scope.notes.splice(i, 1);
    });
  });
}

What’s happening here will make more sense once we have the views set up, but notice that we are defining the addNote and removeNote actions, which the user will initiate and which will go to the server. Also, we have prepared the client-side socket for the list, newNote,and deletedNote actions coming from the server.

To prepare our app’s views, let’s install two more modules: ejs and express-ejs-layouts. Go to package.json and update it accordingly:

myNotePad/package.json

{
  "name": "notepad",
  "description": "a simple note creator app",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "express": "4.0.0",
    "ejs": "1.0.0",
    "socket.io": "0.9.16",
    "express-ejs-layouts": "0.3.1",
    "nedb": "0.10.5"
  }
}

And head back to your terminal again and run npm install.

That’s it for modules! Promise!

Now add a folder called views and add two files to it, layout.ejs and index.ejs (.ejs means an embedded-javascript file):

myNotePad/views/layout.ejs

<!DOCTYPE html>

<html ng-app>
  <head>
    <script type="text/javascript" src="/socket.io/socket.io.js"></script>
    <script type="text/javascript" src="/angular.min.js"></script>
    <script type="text/javascript" src="/AppController.js"></script>
    <title>My Notes</title>
  </head>

  <body ng-controller="AppController">
    <%- body %>
  </body>
</html>

myNotePad/views/index.ejs

<h1>Welcome to NoteMaker! Woo!</h1>
<table>
  <tr>
    <th>Title</th>
    <th>Body</th>
  </tr>
  <tr>
    <td colspan="2">
      Title: <input type="text" ng-model="title" />
      Body: <input type="text" ng-model="body" />
      <button ng-click="addNote()">Add note</button>
    </td>
  </tr>
  <tr ng-repeat="note in notes">
    <td>{{note.title}}</td>
    <td>{{note.body}}</td>
  </tr>
</table>

<button ng-repeat="note in notes" ng-click="removeNote(note)">Remove Note</button>

Both these files prepare our views to access just about everything we’ve written so far. The layout file does all the essential script importing and prepares the app for Angular.js (and sets the layout of the app, of course); and the index file uses Angular.js to receive and display user’s notes.

Finally, let’s update our app.js file to ensure that our views get pulled in:

myNotePad/app.js

var http = require('http'),
  path = require('path'),
  express = require(‘express’),
  app = express(),
  server = http.createServer(app),
  io = require('socket.io').listen(server),
  expressLayouts = require('express-ejs-layouts');

var notes = require('./data/notes');
server.listen(3000);

app.set('view engine', 'ejs');
app.set('layout', 'layout.ejs');

app.use(expressLayouts);
app.use(express.static(path.join(__dirname, 'public')));

app.get('/', function(request, response) {
  response.render('index.ejs');
});

io.sockets.on('connection', function (socket) {
  notes.list(function (err, documents) {
    socket.emit('list', documents);
  });

  socket.on('addNote', function (note) {
    notes.create(note.title, note.body, function () {
      io.sockets.emit('newNote', note);
    });
  });

  socket.on('removeNote', function (note) {
    notes.remove(note._id, function () {
      io.sockets.emit('deletedNote', note);
    });
  });
});

All right! Head to your terminal and run node app.js. You can now add and delete notes.

You have completed your first(maybe?) app using Node.js. Congratulations!

Section 8 – Doing More

Here are two more features you can implement on your own:

  • Let users edit notes.
  • Create a complete note show view that lets users view notes based on their ids (/:id), and make every note a link to that show view.

As always, thanks for reading, and let me know if you have any questions.

Have fun!