Thursday, 8 November 2012
PDF.js and the Rails Asset Pipeline
Wednesday, 17 October 2012
Meteor.js on appfog revisited
Previously, I've written about deploying a meteor.js application on appfog. Unfortunately, meteor have recently released updates (0.4.1 and 0.4.2) that require node.js 0.8 instead of 0.6. Appfog only supply node.js up to 0.6, meaning that until Appfog updates its stack, applications using recent versions of meteor don't seem to be deployable there.
Until that time, I'm using the hosting available directly through meteor.js for my application demos.
Tuesday, 9 October 2012
Using Amazon to scale JMeter
Most of the art of load testing is discovering the right question. Once you know the question, the right approach almost always becomes clear.
For example, when we wanted to know how a Rails app scaled, we picked Apache Benchmark. This worked well, producing the solid statistical evidence we were searching for, to be graphed and digested within a report.
Last month, we were asked to load test an application, to discover whether the audience could be safely let loose to play at a demo: Would the user experience be good enough at the expected load?
For subjective criteria, hard numbers are often tricky to interpret and may be misleading. Loading the system, then allowing users to evaluate the perceived performance is often a more revealing route. Apache JMeter simulates complex user interactions well, so running one scripted instance per expected user seemed a promising strategy.
A good plan in principle, but one that needed 40 spare machines and big fat pipes. Time for Amazon EC2.
Taking advantage of Amazon's free tier, we opted to avoid the API learning curve by hand crafting.
- Through the web interface we
- Installed (JMeter and the load simulation) over
ssh
, scripting in multi-threaded Ruby to avoid IO bottlenecks. - Started the simulations.
- Played with the app, evaluating subjective performance at load.
- Remembered to destroy all instances in every region
All very smooth :-)
Saturday, 29 September 2012
TDD with jQuery thoughts
Monday, 24 September 2012
jsPlumb
I've been using jsPlumb in a recent project to draw some fun visualisations in conjunction with meteor.js and my thoughts on jsPlumb are very positive. jsPlumb is fast to load, draw and redraw connections, it integrates with various different JS frameworks and it's pretty simple to use. About the only criticism I have is that it would be nice if you could influence the connection routing with a bit more precision, or simply have the ability to set up some elements that the connector should try to avoid.
Integrating the library with meteor.js was as easy as placing the jquery jsplumb plugin file into the client/lib directory of the project.
Monday, 17 September 2012
RSpec with Turnip on Gentoo
Turnip is a cool RSpec extension, bring the goodness of Gherkin business readable DSL. But - like Gherkin - it's sensitive to shell encoding. I run Gentoo, so to fix Encoding::InvalidByteSequenceError
I use
export LANG=en_US.UTF-8
Thanks to stackoverflow
Thursday, 13 September 2012
Meteor.js on Appfog
I also also set the ROOT_URL environment variable for my application as I wanted to generate absolute urls from meteor.
Previously, I also needed to set the PORT environment variable to $VMC_APP_PORT but this no longer appears to be necessary. If it is necessary for future deployments, the same process is used as for the MONGO_URL variable.
fibers
package bundled with meteor. This was solved by removing the bundled package and reinstalling the fibers
package from NPM with the bundled code. As this is needed each time, I wrote the following short script to automate the process (and also store the code that was released).
With this script in place, I can now deploy to Appfog reliably whenever I need to, without having to remember a set of file modifications.
Thanks go to http://blog.philkershaw.me/2012/06/deploy-meteor-to-appfog.html as the starting point for my deployment.
Wednesday, 12 September 2012
Internet Explorer Console Shim
Chrome is my weapon of choice when developing rich CoffeeScript and JavaScript apps. This means shaking out all those little differences with IE9 towards the end of a project, and learning to live with all sorts of foible.
Turns out that that IE doesn't always play well with console
.
In particular, on IE9 calling console.debug
fails with
Object doesn't support property or method 'debug'
Since console.debug
is deprecated, I took this opportunity to grep
and replace console.debug
calls with console.log
but its wise to remember to add the console shim for troublesome older versions.
Tuesday, 11 September 2012
beforeunload events in Internet Explorer 9
Chrome is my weapon of choice for JavaScript development. This means spending a little bit of time with
IE9 when development's almost over, learning to play with its little ways. We were taking beforeunload
to display a dialog whenever the user risks losing data by navigating away — but only then. IE9 (oddly) displays null
in a dialog when null
is returned from beforeunload
. Returning undefined
instead means harmony amongst browsers. Another little trick to add to the playbook...
IE9 on Rails in Development
The asset pipeline is one of my favourite Rails 3.1 features. Assets — such as JavaScript and CSS files — are served as written in development mode. As a default, this is spot on but when debugging a rich app on IE9, I found some tuning needed. In particular, IE9 has a hard limit of 31 stylesheets. In this case, it's useful to switch on asset compilation in development. Read on to see how...
JSparklines is a cool JQuery plugin for drawing sparklines — small, in-line graphs. This library uses css injection. In development mode, IE9 raised an Invalid argument
error when this was called. A little bit cryptic, but after a little digging, the cause turned out to be that hard limit. Time to tinker.
To serve fully processed assets in development: edit config/environments/development.rb
, setting
config.assets.debug = false
Thanks Dennis Reimann for his clear example.
Thursday, 9 August 2012
Tidy Assets on Rails
The rails 3.2 asset pipeline is great, but it's good to keep that pipe clean and tidy. Reduce the clutter, and everything is much easier to find. Factoring out assets into gems DRYs (as well as tidies). With rails plugin new
, this is now quick and easy. Thanks to RakeRoutes for crafting a fine step-by-step introduction.
Monday, 30 July 2012
RABL on Rails
There are plenty of ways to output XML from Ruby. So, when it was time for an existing Rails app to move on from to_xml to support a richer API we were able to go shopping...
Following our Agile principles, we focused only on what we needed today. In this case, we went looking for an open source solution with these qualities:
- concise
- quick
- to configure
- to integrate
- to learn
- and readable.
RABL measured up admirably. Kudos to nesquena and the rest of the RABL crew.
Is RABL the ultimate mapper? Maybe it is, but I think it more likely that there's no silver bullet...
Thursday, 12 July 2012
Remember to clear requests between jasmine-ajax tests
We use Jasmine for test-driven CoffeeScript. To unit test Ajax, we rely on jasmine-ajax to spy, mock and fake. A basic usage pattern is to jasmine.Ajax.useMock()
then check mostRecentAjaxRequest()
, but remember to clearAjaxRequests()
to avoid inconsistency (when running as part of a larger test suite).
Taking a look at the source, clearAjaxRequests()
is not called within the code. When running several tests are run in the same browser page, stale requests from previous tests may be returned by mostRecentAjaxRequest()
.
So, instead of jasmine.Ajax.useMock()
then check mostRecentAjaxRequest()
, adopt this pattern:
beforeEach ->
clearAjaxRequests()
...
afterEach ->
...
clearAjaxRequests()
it "should save the JSON data using Ajax", ->
jasmine.Ajax.useMock()
...
request = mostRecentAjaxRequest()
...
Tuesday, 3 July 2012
CoffeeScript and the Curious Case of the Missing Bracket
Over the last month or two, I've grown to admire CoffeeScript. This little language encourages developers to drop braces, sprinkling liberally around enabling syntactic sugar. But there is one area where I think a little more would help a lot.
I sometimes find it useful to think of JavaScript as just a functional language dressed up in someone else's Object Oriented clothes. Passing a function (rather than its value) is as simple as dropping its braces. So, for example alpha = bar.foo
assigns the function foo
on bar
to alpha
. Use alpha = bar.foo()
to assign the value instead.
Objects and classes in CoffeeScript feel more natural, yet bar.foo
still refers to the function foo
. Intuitively, this feels wrong, and the only reason I can fathom for introducing this inconsistency is compatibility with JavaScript behaviour. This price seems too high for such little gain.
I suggest that, in CoffeeScript, bar.foo
should call foo
on bar
with no parameters (just like bar.foo message
passes message
to foo
on bar
), and special syntax be introduced for function passing: bar.foo!
perhaps...
Wednesday, 20 June 2012
A Rhodes Journey - Getting started with RhoStudio on OSX Lion
We started checking out Rhodes a year ago when using Snow Leopard as a development platform, and developed some trial apps. At that time, Rhodes used to be a simple gem that could be downloaded using the compatible Ruby (v 1.8.7) and rvm. Since I recently upgraded to Lion, I thought I'd give Rhodes another spin to see if it had changed. Indeed, I found that RhoMobile has grown by leaps and bounds, and that Rhodes is now a small part of a much larger scheme of things: Rhodes now ships within Motorola's Rhomobile Suite which includes, apart from Rhodes, an IDE called RhoStudio for developing RhoMobile applications, and two other frameworks called RhoConnect and RhoElements.
In this post I'll explain how I went about setting up Rhodes 3.3.3 from the RhoMobile suite and running the sample APIs app for Rhodes (included with the RhoStudio installer) on iOS and Android simulators using the RhoStudio IDE.
Installing the Prerequisites
XCode
Here, we select the relevant iOS device simulators and XCode command line tools, which is a prerequisite of installing RVM on OS X.
Note: if you don't want to develop for iOS and still want to install RVM (without installing XCode, as it is a heavy download), then you might need to install the gcc compiler for Mac to proceed.
Android SDK
RVM and Ruby
Java Development Kit (JDK)
Installing RhoMobile Suite, RhoStudio and Rhodes
gem install rhomobile-debug
gem install "/Volumes/Motorola RhoMobile Suite Installer/.gems/rhodes-3.3.3.gem"
gem install rhodes-translator
Building and Running the sample APIs application
Within the Rhomobile suite installer downloaded earlier, go to samples and copy the rhodes-system-api-folder to your workspace folder specified earlier. In RhoStudio, import the project by selecting File > Import > Existing Project into workspace. Choose the root folder as the workspace directory to see the project in the list. Select the project and click Finish. The project should now be listed in the Project Explorer.
Using the Android simulator
After the installing the SDK platform, we also need to install the 'Google APIs' displayed under the installed SDK in the SDK manager. This is used by some Rhodes libraries in the kitchensink project.


Note: If it fails with a message requesting you to run 'set-rhodes-sdk' then do so in the project directory in the terminal and try running again. The application takes between 2 to 5 minutes to launch on an android simulator.
Using the iPhone simulator
All Done!
This concludes a walkthrough of how to set up Rhodes and RhoStudio on Mac OS X Lion.We can now proceed to creating Rhodes apps for both Android and iOS platform with (hopefully) less effort than writing apps in separate native environments.
Thursday, 7 June 2012
A Scope Gotcha In CoffeeScript
I think CoffeeScript a fine little language, and — after developing with it throughout May — have grown to like it a lot. However, hidden amongst all the smooth elegance are a few rough edges, to confuse and cut the unwary. Like me. This is the story of a small scope that caught me out twice.
Thanks to JQuery, I might implement a widget to manage a list of items a little like this, and when the user clicks the fat arrow sets a context allowing an easy call to my new object.
class Foo
constructor: ->
@items = []
doSomething: ->
buildList: ->
$ul = $('<ul/>')
for item, index in @items
$li = $('<li/>')
$li.on 'click', =>
$li.addClass 'active'
@doSomething()
false
$ul.append $li
Except this doesn't quite work. To see why the active
class ends up on last list element, take a look at the compiled JavaScript:
var Foo;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Foo = (function() {
function Foo() {
this.items = [];
}
Foo.prototype.doSomething = function() {};
Foo.prototype.buildList = function() {
var $li, $ul, index, item, _len, _ref, _results;
$ul = $('<ul/>');
_ref = this.items;
_results = [];
for (index = 0, _len = _ref.length; index < _len; index++) {
item = _ref[index];
$li = $('<li/>');
$li.on('click', __bind(function() {
$li.addClass('active');
this.doSomething();
return false;
}, this));
_results.push($ul.append($li));
}
return _results;
};
return Foo;
})();
Oops - $li
is defined right at the top of buildList
. The context will contain the current value, from the last iteration.
There are several ways to improve this code and make this problem go away. One easy technique is just to factor out a method to build the list item.
class Foo
constructor: ->
@items = []
doSomething: ->
buildListItem: (item, index) ->
$li = $('<li/>')
$li.on 'click', =>
$li.addClass 'active'
@doSomething()
false
$ul.append $li
buildList: ->
$ul = $('<ul/>')
for item, index in @items
$ul.append @buildListItem item, index
Though this applies equally to JavaScript, I think that the very cleanness of CoffeeScript allows this sort of bug to creep in more easily. The lesson to take away — keep CoffeeScript methods small and objects well factored.
Wednesday, 30 May 2012
New Relic development mode
Just add the gem to your application, install and restart, and visit the path
/newrelic
to see it.Once again, Newrelic is awesome :)
Wednesday, 23 May 2012
Rice is Nice for Jasmine On Rails
Test first JavaScript seems topical. Let me explain a little about how we do it here at Hedtek...
For continuous integration, we run Jenkins. To unit test CoffeeScript and JavaScript, we use Jasmine. For rich apps on Rails, we use jasminerice to push Jasmine into the testing asset pipeline. Last week, we took a look around for a smooth way to integrate this continuously, and settled happily on jasminerice-runner.
When I see an open source project with a handful of documentation, a question springs to mind: can it really be this easy?
With jasminerice-runner, it is.
Just
#= require jasminerice_reporter
rake jasminerice:run
Good stuff, gaslight.
Thursday, 10 May 2012
First Time Heroku, Precompiling Assets
Heroku provides PaaS in the cloud, and is well known as a host for Rails apps. Last week, my first opportunity arrived to find out whether Heroku is as good as they say. I wasn't disappointed.
Following the documentation, everything progressed smoothly: signing up, installing Heroku Toolbelt, initial login, creating the cedar stack and the final push — except asset compilation. By default, Heroku continues even if asset compilation fails. So always read the output carefully:
$ git push heroku master
...
-----> Heroku receiving push
-----> Ruby/Rails app detected
-----> Installing dependencies using Bundler version 1.1.2
...
-----> Writing config/database.yml to read from DATABASE_URL
-----> Preparing app for Rails asset pipeline
Running: rake assets:precompile
rake aborted!
could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
Tasks: TOP => environment
(See full trace by running task with --trace)
Precompiling assets failed, enabling runtime asset compilation
Injecting rails31_enable_runtime_asset_compilation
Please see this article for troubleshooting help:
http://devcenter.heroku.com/articles/rails31_heroku_cedar#troubleshooting
-----> Rails plugin injection
...
One simple way around an asset compilation issue is to:
- Compile locally
$ bundle exec rake assets:precompile
- Commit assets to git
$ git add -f public/assets/ $ git commit -m "Precompile public assets"
- Push
$ git push -f heroku master
And — after heroku run rake db:migrate
— everything's great
-----> Writing config/database.yml to read from DATABASE_URL
-----> Preparing app for Rails asset pipeline
Detected manifest.yml, assuming assets were compiled locally
-----> Rails plugin injection
or at least for me...
Friday, 4 May 2012
Newrelic
How much more awesome do you need? Maybe a really easy setup to get the server monitoring on all your chef nodes?
Then just add your newrelic key to each node to be monitored under
node[:newrelic][:license_key]
Tuesday, 1 May 2012
Monday, 30 April 2012
A "Hello, World" from File by Chef
Friday, 27 April 2012
A "Hello, World" with Attributes from Chef
Wednesday, 25 April 2012
Meteor JS
Last week we decided to do a short spike on Meteor, the JS framework that has gained a lot of popularity over the last few weeks. Some results of this spike are reported here.
PhantomJS On Ubuntu
PhantomJS avoids
make
, autoconf
et al, preferring to roll their own build system. So it's best to grab a binary and follow the installation instructions. For x86
and x86_64
grab the appropriate dynamic build. For other platforms, pick a different tool...And here's how it went...
Saturday, 21 April 2012
Performance at load of a Rails front end and DSpace implemented repository
We measured performance of a combination of a Ruby on Rails front end, a modified DSpace REST API, and an instance of DSpace. Measurements were performed over a University intranet segment using ApacheBench.
The report that contains a very comprehensive set of performance graphs for different kinds of accesses at different load levels.
Download the report.
Friday, 20 April 2012
Compiled asset woes
One that has recently been an issue for us is a cascade of behaviours that individually are all perfectly reasonable but, when combined, leave you with major headaches.
When you compile your assets with you get (as expected) your files, in compiled, minified form in the folder
public/assets
.Files in public/assets are served in preference to anything produced by the Rails stack (they shadow your controllers). Perfect behaviour for caching, disabling certain routes, etc. and makes sure you are familiar with how things would act with a web server in front of Rails.
In development mode, Rails will serve all your javascript files separately, while precompiled only the manifest files will be present. So in development, you may have several (or even dozens) of files, while in production you only have one. Again, fantastic behaviour for caching, reducing requests and a whole host of other things.
In combination with precompiled assets though, it's disastrous. Your top level file (assets/application.js) in development is pretty much empty, but compiled contains all or almost all of your application's javascript. If the compiled version gets served in development then all your javascript is sent to the browser twice... and this is almost certainly going to break things.
If you're lucky and you have a light javascript application, the most you may notice is some effects not working correctly, maybe you'll investigate briefly on production and see it works fine, put it down as a development machine problem (or you'll solve the problem and never think about it again until it happens again).
On a heavy javascript application with a lot of javascript running in the browser, chances are your entire application will simply not work. If you aren't aware of the cascade of issues, this can take a long time to solve.
If you're running automated tests against everything (using tools like capybara-webkit or poltergeist) then the situation is slightly changed. In the test environment, Rails doesn't serve separate assets in a single file. But the file will still be served from public/assets in preference to the Rails stack, so your tests will run against the last version you precompiled. Again, this can be very confusing and even if you're aware of the previous behaviour it can take you a while to work out why tests that run fine on one machine (with no precompiled assets) don't work on another (where you precompiled assets last week for a demo and haven't cleaned them out).
Is there a solution? Yes, there's a very simple one. Simply configure Rails to serve your assets from a different location depending on environment.
Add the line to
config/environments/development.rb
file and a similar one to config/environments/test.rb
and the problem is now gone and you can compile assets on any machine without fear of causing issues if you forget to clean them up.
Thursday, 19 April 2012
HTML5 Local Storage
Or at least as well as could be expected...
Some important consequences follow from the specification. In particular, local storage is sandboxed by domain — or more precisely [scheme, host, port] origin. Any script from the same origin shares the same local storage.
If you seek a secure local data stash for an authenticated user, local storage is not the API you're looking for...
Wednesday, 18 April 2012
Ruby On Gentoo with RVM
With a shiny new user and a shiny new
.rvmrc
after cd
(into the directory) I see
==============================================================================
= NOTICE
==============================================================================
= RVM has encountered a new or modified .rvmrc file in the current directory =
= This is a shell script and therefore may contain any shell commands. =
= =
= Examine the contents of this file carefully to be sure the contents are =
= safe before trusting it! ( Choose v[iew] below to view the contents ) =
==============================================================================
Do you wish to trust this .rvmrc file? (/home/hedtek/space/.rvmrc)
y[es], n[o], v[iew], c[ancel]> y
Trying to install bundler then fails with
$ gem install bundler
/home/hedtek/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/
site_ruby/1.9.1/rubygems/custom_require.rb:36:
in `require': cannot load such file -- auto_gem (LoadError)
from /home/hedtek/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/
site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
Turns out that the Gentoo defaults don't play well with rails development. Easy to fix by an unset
when starting a development session:
$ unset RUBYOPT
Once this has been done, all is good:
$ gem install bundler
Fetching: bundler-1.1.3.gem (100%)
Successfully installed bundler-1.1.3
1 gem installed
Installing ri documentation for bundler-1.1.3...
unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT
to UTF-8 to US-ASCII for lib/bundler/vendor/thor/invocation.rb, skipping
Installing RDoc documentation for bundler-1.1.3...
unable to convert "\xC3" to UTF-8 in conversion
from ASCII-8BIT to UTF-8 to US-ASCII
for lib/bundler/vendor/thor/invocation.rb, skipping
Thanks to this post for setting me on the right road...>
Monday, 16 April 2012
Brief Foray into HTML5 File APIs
It turns out this is quite easy to do, although a bit verbose. You need to:
- Create a FileReader.
- Set an event handler for the onload event.
- Pass the file(s) you want to read to the appropriate reading method.
MyApp.Views.file = Ember.View.extend
tagName: 'input'
attributeBindings: ['type', 'id']
type: 'file'
change: (e)->
view = this
reader = new FileReader()
reader.onload = (e)->
view.set('file', e.target.result)
reader.readAsText(e.target.files[0])
This can then be invoked in a handlebars template as follows:
{{view MyApp.Views.file fileBinding="SomeModel.attribute" }}
I expect this approach to be unsuitable for extremely large files as it will read the entire file into memory and transmit it as part of the payload rather than as a file upload, for some value of extremely large...
Wednesday, 28 March 2012
A "Hello World" from Chef
An efficient feedback loop matters to me, and isolation between projects. Installing a server and setting up a workstation for each project sounds too slow.
So use chef-solo[1]
$ chef-solo --version
Chef: 0.10.8
in a workspace for project hello
$ mkdir --parents chef-workspace/hello
$ cd chef-workspace/hello
under version control
$ git init
Isolate the new project from its environment by grouping the configuration files together
$ mkdir config
and separate them from the code
$ mkdir cookbooks
A minimal configuration to wire in this project layout, setting the conventional cookbook_path
, may be written in Ruby
cookbook_path File.expand_path(File.join(File.dirname(__FILE__), '..', "cookbooks"))
Save this into config/chef-solo-config.rb
, a reasonable naming convention for the configuration file passed to chef-solo
. Attributes declaring the exercise are passed through a second file, encoded in JSON. A minimal Hello, World
exercise, running just the default recipe from a cookbook called hello_world
, is
{"run_list": ["recipe[hello_world]"]}
Save this config/from-hello_world-run-default.json
, a conventional name for an exercise that runs the default recipe from the hello_world cookbook. Create a directory for this cookbook
$ mkdir cookbooks/hello_world
with space ready for a recipe
$ mkdir cookbooks/hello_world/recipes
Chef supports logging out-of-the-box, and so an easy way to say hello is
log("Hello, World") { level :info }
Save this into cookbooks/example/recipes/default.rb
, and Chef will run this when the no recipe name is given (for this cookbook).
Ready to cook[2]
$ sudo chef-solo --config config/chef-solo-config.rb
--json-attributes config/from-hello_world-run-default.json
[...] INFO: Starting Chef Solo Run
[...] INFO: Replacing the run_list with ["recipe[hello_world]"] from JSON
[...] INFO: Hello, World
[...] INFO: Chef Run complete in 0.885143 seconds
Hello, World
— served up by Chef.
Simple.
A few more sophisticated examples are queued in the draft pipeline, so check back later for more on Chef - or subscribe to the feed.
[1] Chef moves fast: install the lates
[2] unless you forget to
sudo
$ chef-solo --config config/chef-solo-config.rb
--json-attributes config/from-hello_world-run-default.json
[...] FATAL: Failed to read the private key /etc/chef/client.pem:
#<Errno::EACCES: Permission denied - /etc/chef/client.pem>,
/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:59:in
`read'/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:59:in
`load_signing_key'/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:33:in
`initialize'/usr/lib/ruby/1.8/chef/rest.rb:40:in
`new'/usr/lib/ruby/1.8/chef/rest.rb:40:in
`initialize'/usr/lib/ruby/1.8/chef/client.rb:54:in
`new'/usr/lib/ruby/1.8/chef/client.rb:54:in
`initialize'/usr/lib/ruby/1.8/chef/application/solo.rb:180:in
`new'/usr/lib/ruby/1.8/chef/application/solo.rb:180:in
`setup_application'/usr/lib/ruby/1.8/chef/application.rb:61:in
`run'/usr/bin/chef-solo:24
/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:62:in
`load_signing_key': I cannot read /etc/chef/client.pem,
which you told me to use to sign requests!
(Chef::Exceptions::PrivateKeyMissing)
from /usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:33:in `initialize'
from /usr/lib/ruby/1.8/chef/rest.rb:40:in `new'
from /usr/lib/ruby/1.8/chef/rest.rb:40:in `initialize'
from /usr/lib/ruby/1.8/chef/client.rb:54:in `new'
from /usr/lib/ruby/1.8/chef/client.rb:54:in `initialize'
from /usr/lib/ruby/1.8/chef/application/solo.rb:180:in `new'
from /usr/lib/ruby/1.8/chef/application/solo.rb:180:in `setup_application'
from /usr/lib/ruby/1.8/chef/application.rb:61:in `run'
from /usr/bin/chef-solo:24
Tuesday, 27 March 2012
Starting with ember.js and Rails
After some investigation, I found some useful posts on setting up an Ember.js application, one rails specific and one that introduces a layout system and a routing system. This prompted some experimentation to set up a front end that is manageable, suits the project and allows us to quickly add to the front-end.
The end result is a set of generators and asset-pipeline suitable gems for quickly getting started with Ember.js. The first thing to note is that the generators are opinionated - they assume you are using CoffeeScript and Haml within the Rails asset pipeline. To help with this, the bootstrap generator adds the appropriate gems to your Gemfile.
More details can be found in the git repositories for the 4 gems created for the project: