Hacker News new | past | comments | ask | show | jobs | submit login
How to Wire Up Ruby on Rails and AngularJS as a Single-Page Application (angularonrails.com)
109 points by jasonswett on July 22, 2014 | hide | past | favorite | 33 comments



We (10KB) have built our own CMS combining Rails and AngularJS. Our main goal for our CMS was to turn every website made with it in a Single-Page Application, but at the same time maintain support for server-side rendering.

We loved the combination of Rails and AngularJS, but we didn't like that we had to write a lot of stuff twice (ie. Rails routes & Angular routes, Rails controllers & Angular controllers). Therefore we have written quite some glue code to automatically generate AngularJS code from our Rails code. I have been wanting to make a full write-up of all our experience in combining Angular & Rails for a while now, but didn't get to it yet. I did write-up a quick and dirty way to automatically generate Angular Resources from you Rails controllers, though. (http://10kb.nl/blog/automatically-generate-angular-resources...)

And, if anyone has any questions about combining Rails & Angular feel free to shoot me an e-mail.


I'm building something like this, but in node: https://github.com/martindale/maki


That's an awesome idea. I'll definitely check your stuff out.


Nice work! I've put up a similar (but much simpler) demo and blog post: https://github.com/jesalg/RADD


Nice. I think your Angular/Devise work will probably end up being helpful for me.


Great write up! I wrote a bit[0] awhile back about setting html5mode routing with rails and angular using a similar setup which may be a useful addon to this article.

[0] http://mbell697.github.io/2014/02/04/yeoman-angular-rails-ht...


Thanks! I'll check it out.


I've been using a similar setup for some time now. The most significant obstacle for me was user authentication. For anyone else who needs to add auth support to Angular + Rails:

https://github.com/lynndylanhurley/ng-token-auth https://github.com/lynndylanhurley/devise_token_auth


Nice writeup. I tried to do the same thing a few months back and gave up. How did you handle getting your browser to talk to a server running on a different port? (Cross-origin requests).

I have to say though, Rails used to be known for "convention over configuration", but when I've tried to use it lately I've found it becomes almost as complicated as configuring enterprise Java projects.


I didn't have to do anything special to allow CORS, and now that I think of it I'm not sure why, because it's been necessary on other SPA projects I've been involved with. Maybe because both servers are localhost. That would be a good thing for me to figure out and include in the post. I'm kind of learning all this in public.


> How did you handle getting your browser to talk to a server running on a different port? (Cross-origin requests).

https://github.com/cyu/rack-cors

I used that gem recently, and it fixed my issue. Just added the dev, prod hostnames explicitly in the origins list in my application.rb.


> How did you handle getting your browser to talk to a server running on a different port? (Cross-origin requests)

Having run such things on entirely different servers, never mind localhost ports, what I needed to do was set the Access-Control-Allow-Origin http header in the rails controller (same principle applies to other frameworks). One simple guide is here: http://madhukaudantha.blogspot.co.uk/2011/05/access-control-...

Slightly ruined by that dreadful blogger interface, but there you go.


I wrote about using Rails + AngularJS in a CORS way -- http://dojo4.com/blog/angularjs-service-rails-api

Hopefully it helps you!


>I have to say though, Rails used to be known for "convention over configuration", but when I've tried to use it lately

>I've found it becomes almost as complicated as configuring enterprise Java projects.

Do you have any specific examples of where you were having troubles?


> How did you handle getting your browser to talk to a server running on a different port? (Cross-origin requests).

He's using grunt-connect-proxy to proxy the API requests through the grunt server so there are no CORS requests in this setup.


You could just run the api on /api via an nginx proxy, that way it uses the same domain. I.e. catch all the traffic coming in to /api and route it to the proxy for you rails app.


I wrote up a guide to this along the lines of "here are things I didn't do when doing my first Rails / AngularJS app":

http://thomasleecopeland.com/2014/03/12/doing-a-rails-angula...


Fyi promise unraveling has been deprecated after Angular 1.2. So it should be

  Group.query().then(function(groups){
   $scope.groups = groups;
})


Do you have a link to any discussion on that?

It looks like the docs still suggest the method used in the blog post: https://docs.angularjs.org/api/ngResource/service/$resource

"It is important to realize that invoking a $resource object method immediately returns an empty reference [...] Once the data is returned from the server the existing reference is populated with the actual data. This is a useful trick since usually the resource is assigned to a model which is then rendered by the view. [...] This means that in most cases one never has to write a callback function for the action methods."



Thanks. Okay, that makes sense.

The $resource usage described still works in version 1.2.19, with no promise unwrapping options set. I could be wrong, but I think it is because the $resource returns a reference to an empty object that has values copied into it when the call completes. The actual promise is a property named $promise on the returned object.

Example: http://jsfiddle.net/92zmG/7/


Why RAILS::API instead of something like rabl?


Rails-api is a gem that configures rails in a more lean and mean fashion for API usage, it doesn't handle the json serialization. Mostly rails-api disables a lot of default rails features/middlewares that aren't needed when you're only building an API.

For json serialization you may want to look at Active Model Serializers[0], I found it much easier to work with than rabl, and it's also written by the rails-api group.

[0] https://github.com/rails-api/active_model_serializers


AMS maintainer here, I'm making a big announcement about it soon.

That said, you're correct, AMS <-> RABL is the right comparison, not Rails-API <-> RABL.


Where is this AMS announcement going to be? I'd like to watch, since I use AMS extensively (thanks for the great project!)


It'll be on the rails-api-core mailing list: https://groups.google.com/forum/#!forum/rails-api-core


Hmm. Unless I'm crazy, RABL is a totally different thing for a different purpose. RABL is a tool (as is the analogous JBuilder, the default JSON-rendering-thingy for full-blown Rails) whereas Rails::API is a framework.


Why is grunt needed? Is it because he's using Rails::API?

Most setups I've seen just let Rails serve the templates.


grunt is the build tool for the Angular.js side of things. It is doing a lot of other html front end stuff to make the SPA.

Also grunt has a watch process that see code changes, it will then compile them and have the server get the browser to reload content to get the new version.

When this gets deployed to your production server, you will probably use the same server process that handles the Rails requests. grunt is for development only.


This is a pretty good tutorial, that seems to be poorly covered in the body of recent(ish) blogs.


Thanks!


Is this an isomorphic set up? Or does the front end do ALL templating?


No, not isomorphic.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: