I dove into the very nice screencast on Sails and was captivated – a framework that does a lot of the work for me! This could be great. I did check – briefly – for a leading MVC framework for Node.js (akin to Rails for Ruby, Django for Python, etc.), but did not find a true leading project that stood out. Even though Sails was pre-v1, it seemed complete enough to get going.
I installed it, and got to hacking away creating a nice backend API for my project. Creating controllers and models went well. Policies seemed to work OK – I got hung up on exactly what was going on for quite some time, as I did not recognize that if a model exists, the same controller will be automatically created behind-the-scenes; however, the framework did differentiate between singular vs plural. And coming from a recent Rails background, I was rather opinionated about how I wanted it structured. So I ended up having to write all my own controllers, along with all my own routes. Very quickly my hopes of a framework that would let me build quickly fell apart.
The asynchronous nature of Node really tripped me up. I’m very much used to the blocking nature of other languages, and I find it easy to work with. For example, if I’m creating an instance of a model, which has associated models, and I need to save the parent instance before saving the associated models, I end up in callback hell. Why can’t it be as simple as making a method call, and then on the next line making the next method call? I ended up with the async.js library doing a lot of work, which clearly took away from the benefits of using node. This is not a gripe about Node – it’s a gripe about my skills (or lackthereof, in this case).
The second factor was a conversation I had with a colleague about using tools for building new projects. He brought up a few good points – first, using tools you know allows you to prototype much faster, as you’re not stuck learning something new in addition to building something that you don’t even know will be around in a few months. Secondly, the experience you have from those tools can really only be a benefit going forward – yes, in my case, Ruby is “slow”, and Rails has a lot built into it, but it’s also got a humongous community that I can tap into about how to speed up Ruby, and how I can make Rails perform much faster if necessary. I also know enough about Ruby and Rails to not be completely lost when researching, talking with others in the community, or needing to write extensions of my own or dive into the source code.
There you have it. The challenges I faced with Node, Sails, combined with the benefits of using technologies I already know led me to abandon Sails for this project, and keep going with Rails. But for those of you that are familiar with Node, and are looking for an actively-developed MVC framework, I strongly recommend you check out Sails. It’s fantastic, and it’s got a great, growing community. I just don’t have the time to learn nor to contribute (as much as I would love to); perhaps my next project will be in Sails!
I recently decided to switch to using Rails for a new project from Sails.js (I’ll detail the reasons in another post), and decided to take advantage of the latest-and-greatest. Ruby 2.0 is officially released and Rails 4 is on rc1, so I figured it’d be worth some small headaches to just jump on the bandwagon now, rather than using 3.x and attempting to port in all the nice things Rails 4 provides.
Having worked with Rails for the last year, and getting more and more comfortable with rspec as time goes on, I decided to start this project the “right way” and do TDD. To that end, I decided to start the app by installing rspec, guard and zeus to make sure I have a fast test suite. The following is the adventure these gems took me on as I attempted to get them all playing nice with Rails 4.
So to start, I installed the gems (and associated gems):
Create a `script` directory, and in it create the following file:
This will be used to configure RSpec within Zeus to play nice with Rubymine (since Rubymine brings a lot of its own libraries and packages).
Next, we need to start zeus with the correct RUBYLIB environment variable, again to account for Rubymine:
To finish setting up RSpec within Rubymine, we need to update the default configuration to use the new runner we just created.
Go into your Run/Debug configurations, select “Defaults”, then “Rspec”. Check the box that says “Use custom RSpec runner script:”, and in the text field that becomes editable enter the appropriate path to the runner script we created; e.g. “/path/to/my/project/script/rspec_runner.rb”.
To start, create a new run configuration by selecting “IRB Console”, and fill in the “IRB Script” line with the path to your rspec bin file. If you’re using RVM on OS X, it’ll be something like: “/Users/pragone/.rvm/gems/ruby-2.0.0-p0@example-app/bin/guard”. Set the working directory to the project’s root directory, and you’re off to the races!
The one downside is that I still haven’t found a nice way to *start* zeus within Rubymine; I still start it in the console (using our new script/start_zeus script: `ruby script/start_zeus`); after that, however, I just run the “Guard” configuration we created in the last step.
After all this, however, I still ran into problems. In the end, it was a misconfiguration in my spec_helper.rb file that was causing problems. Specifically, I had `require ‘rspec/autorun’` in there, and it should’ve been removed. I’ve attached my spec_helper.rb and Guardfile for reference here: