My students struggle a bit with ActiveRecord for Sinatra and Rails, but they eventually get it.
However, they completely burn out on Sequelize for Node.
To my mind, the biggest difference between Sequelize and AR is that AR is synchronous, whereas Sequelize is not.
Consider:
# ActiveRecord
@post = Post.find(2)
render json: @post
// Sequelize
Post.findById(2).then(function(post){
response.json(post);
});
For small actions like this, the difference is still visible but it doesn't look so bad. With more complicated queries, it's easy to find yourself in callback hell.
So my question is: Why is it OK for ActiveRecord to be synchronous, but bad for a JS ORM to be synchronous?
I understand the disadvantages of synchronous vs. asynchronous. But the disadvantages of synchronicity don't really seem to be hurting ActiveRecord.
The difficulty with Sequelize isn't just that you have to write .then(function(){}) a thousand times; it's also that understanding how callbacks work at all takes a good amount of comfort with Javascript, and since Sequelize is the primary relational ORM for Node, it makes Node much less approachable to beginners. One might say "beginners shouldn't be using Node," but Rails has achieved a tremendous amount of success due to endeavors to make it approachable to novice developers.
It is bad for a JS ORM to be synchronous, because the underlying execution engine (Node.js) is based on an asynchronous event loop based execution model.
The single reason why Node.js scales well, despite being single threaded, is because it uses non-blocking IO and has an active ecosystem of libraries that work well with the non-blocking asynchronous model.
It is exactly because of this, unlike ruby application servers, where a single process is processing just one request at a time, A node.js process can easily juggle a large number of requests as expensive IO operations (like reading from disk, reading from DB, communicating with external services) do not block the process.
In other words, if Node was synchronous then one user's database query would cause the server to "hang" and be unresponsive for all other users until the query completed.

This post elaborates more on the details of the Node.js Event loop.
Now while this is intutive for web developers who have always dealt with callbacks in javascript, it does make things difficult for new developers, who are typically not familiar with callback oriented APIs. However, a few new advancements in Node.js are making things simpler.
Particularly noteworthy are support for generators and async/await functions. Using these features we can eliminate the callback pyramids and use normal try/catch syntax for error handling in asynchronous code as well.
Using a generator based control flow library like co asynchronous code can be written in a linear fashion, taking advantage of generators (which latest Node.js release already supports).
While async/await is not officially available in Node.js yet, it simplifies asynchronous code even further, eliminating the need for libraries like co. Using a transpiler like babel this feature can be used right now - and this is what I would recommend you to consider using in your class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With