AngularJS on Rails
Jun 30 th , 2015
Setup Rails Application
Before we begin, we will need to add a couple gems to our Gemfile. The angularJs-rails gem provides integration with the AngularJS library and our Rails application. The bootstrap-sass gem merely adds bootstrap support so we can focus on the code rather than the style of the app. Add these gems to your gemfile now as listed below.
Now run a bundle install to install the gems:
Next, we need to create a model called Visitor . The Visitor model will represent a visitor that visits. Run the command below to create the visitor model now:
Great, now we need to create a Visitors controller that will give us a way to interact with our model. The Visitors controller will have 3 different actions in this example application. The first action, index will return either the visitors page or a json list of visitors depending on how it is accessed. The second action, create will be responsible for creating the visitor. The final action, destroy will destroy the visitor. Run the command below to create this controller now:
Now let’s modify our routes file to set up the proper paths and add a site root. Open up your routes file and modify it so that it looks like the code listed below:
The code fragment that says defaults:
By default, AngularJS knows nothing of the cross site request forgery (CSRF) protections in our applications. We need a way to tell AngularJS how to interact with our application while obeying the CSRF protections that we have in place. Luckily we have a way to do this. Open up your ApplicationController and add in the code listed below.
If you are using Rails 4.2 and up, use the code below:
If you are still using Rails 4.1, use the code below instead:
The code listed above will create a cookie called XSRF-TOKEN that will contain our form_authenticity_token . Any time a request is made, AngularJS will present that token in the HTTP headers for the request.
Now let’s modify our VisitorsController to allow for access to the Visitor model. Open up your VisitorsController and modify it so that it looks like the code listed below:
The code above is typical Rails code, with the exception being that we return JSON as a result. Since our application will be communicating primarily via AJAX we have no need for HTML other than the index action, which will return either html or json depending on the request type.
Next we need to add support for both AngularJS and Bootstrap to our application.js file. Open up your application.js file and modify it so that it looks like the code listed below.
In the code above we add support for AngularJS as well as Bootstrap. We also add support for a library called angular-resource which allows us to easily talk to our Rails application.
Now let’s add a bit of CSS for bootstrap. Create a new file called bootstrap_config .scss and add in the code listed below:
There is a lot going on here, so i’m going to break it down into pieces. The first line:
defines an AngularJS module. AngularJS modules can be thought of as individual components in your application. You’ll notice we include ngResource as an argument. ngResource provides easy access to RESTful resources such as our Rails application.
The next set of lines:
defines a service, in this case, it ties in the ngResource service mentioned earlier and tells AngularJS how to talk to our application.
The next set of lines:
define a controller. Controllers tell AngularJS how to interact with our application similar to how Rails controllers are used to tell Rails how our views interact with our models.
Let’s break this down a bit:
The outer div on the first line has an attribute called ng-app . The ng-app attribute tells AngularJS that this is part of our AngularJS application. In this case we specify the name of our AngularJS module, VisitorCenter .
The next inner div contains an attribute called ng-controller . This attribute tells AngularJS that we wish to use our visitorsController as the controller for this portion of the application.
The ng-submit attribute on our form tells AngularJS that we wish to use the addVisitor() method on our controller to process the form request. Each of the input elements contain an ng-model attribute. This attribute maps the input elements to our model.
The ng-show attribute on the first row tells AngularJS that we only want to show the row if the condition mentioned is matched. In this case we only want to show the first row if there are no visitors.
The ng-repeat attribute is a loop. This particular loop tells AngularJS that we want to loop through each visitor.
Text contained within << . >> are AngularJS expressions. In this case we are telling AngularJS to render the fields mentioned in each expression.
The ng-click button tells AngularJS to run the specified controller function when the html tag in question is clicked. In this case we run the code to delete the specified user.
So far so good, That’s it. for this introduction to AngularJS and Rails. See ya.
Ruby on Rails на русском
Еще один блог о веб-разработке
Когда я только начал изучать AngularJS, у меня была мысль «зачем всё усложнять, почему ты не держать всё в простом виде?» и «зачем учить ещё одну технологию?».
Дело в том, что когда ваше веб-приложение становится сложнее само по себе, размер вашего кода растет. Если даже не растет его размер, растет его сложность.
AngularJS и другие подобные фреймворки как раз помогают справляться со всей этой сложностью.
AngularJS имеет хорошую организацию, то есть вам легко найти за что отвечает та или иная часть вашего кода. Обновление одной части не должно задевать остальные.
Это будет легче и для вас, и для других разработчиков из вашей команды.
Кроме того, вам не нужно использовать какой-либо код дважды, а многие стандартные действия в AngularJS упрощены и это серьезно повышает продуктивность.
Да и с тестированием в AngularJS все намного проще, чем с тестированием «чистого» JS-кода.
AngularJS отлично интегрируется с Ruby on Rails и другими бэкенд-фреймворками.
Это проект с открытым исходным кодом, разработанный сотрудниками Google.
Эта технология сейчас вполне неплохо востребована, а владеющие ей программисты могут довольно неплохо зарабатывать.
Maintainable I18n with Rails and AngularJS
by Alessandro Desantis
angular-translate is one of the coolest AngularJS modules available out there. It’s elegant, flexible, and extensible beyond common sense.
However, when I was building my first application with Angular and Rails, I found that there was no easy way to test the whole thing with RSpec and Capybara, as I didn’t have access to the translations.
I came up with a few ideas, but they weren’t really ideal (pun intended):
I could write my translations in Rails and then somehow copy them into static JS files, maybe with a Rake task, but it d >It didn’t immediately occur to me that I could somehow serve all the translations via AJAX.
So, I ended up creating a translations_controller.rb:
Then, I configured my application to use angular-translate-loader-static-files (you’ll have to install it separately):
You will also have to add the routes to your config/routes.rb:
Let’s test this! First, we’ll create a HomeController with Angular. To do that, we’ll edit our app.js like this:
And here’s the corresponding home.html view:
Now, we’ll need to put our translation(s) in config/locales/en.yml (or wherever you told Rails to look for them):
If you load your app now, you should see the “Hello, world!” heading.
At this point, writing an integration test with Capybara is quite straightforward. All we have to do is create a spec/features/home_spec.rb file containing something like this:
Note: With a few more lines of code, you could also expand this to have it load only specific domains of your translations instead of everything at once (have a look at angular-translate’s partialLoader if you want to know how).
How to Set Up Authentication with AngularJS and Ruby on Rails
Table of Contents
1.1 Who This Tutorial Is For
Since Rails is old and AngularJS is new (relatively of course), I’m assuming there will be a lot more Rails developers interested in adding AngularJS to their stack than AngularJS developers wanting to learn Rails. If you’re comfortable with Rails but new to AngularJS, this tutorial is perfect for you.
1.2 What You’ll Learn
By the end of this tutorial you should be able to answer the following questions:
- — How do I create an Angular/Rails single-page application at all?
- — How do I use Devise with AngularJS?
- — How do I secure the various pages of my application?
- — How do I write integration tests for my authentication features?
2 Laying The Groundwork
Before it makes sense to start talking about building any authentication features, you’ll of course need to spin up a new Rails project and install Angular. I like to structure my Angular/Rails projects as single-page applications and that’s the structure I’ll be using in this tutorial.
2.1 How To Set Up An Angular/Rails Single-Page Application
Setting up an Angular/Rails single-page application is actually a pretty non-trivial task. I’d recommend checking out another post of mine that walks you through the process in detail. Even if you already know how to set up an Angular/Rails SPA (ARSPA?), I’d still recommend taking a glance at my article to see how I did it. Everything that follows assumes your application is set up in that general fashion.
3 Installing The Necessary Libraries
I’m going to assume you’ve either followed my ARSPA tutorial or done something very similar.
Let’s now start with the small goal of being able to enter a username and password into a login form and then get some signal we’re authenticated. We won’t worry yet about validation or anything like that. Just the «happy path».
The first thing we’ll do is create a new branch for our authentication work:
3.1 The Libraries We’ll Be Using
In order to achieve our authentication objectives we’ll be taking advantage of two excellent libraries: ng-token-auth and devise_token_auth, both written by Lynn Dylan Hurley.
3.2 Installing devise_token_auth
First we shall add devise_token_auth to our Gemfile :
We’ll of course do a bundle install to install the gem. After that we’ll run an additional command to let ng_token_auth add a migration and some necessary configuration.
Now let’s run the migration to create the users table.
Now might be a good time to commit your work.
3.3 Installing ng-token-auth
First, install the ng-token-auth module with bower .
Now add ng-token-auth to your modules. My app.js looks like this:
4 The Login Form
4.1 Adding the Client-Side Code For The Login Form
If you’re familiar with the Devise gem you of course know that they conceive of a «user session» resource that can be created, destroyed, etc. This idea makes sense to me and so I’m going to copy this idea on the client side.
Let’s create a directory in client/app/views called user_sessions .
We can think of a successful user authentication as the creation of a new user session, so we’ll put the login form HTML in user_sessions/new.html . This code is a slightly modified version of the login form example provided in the ng-token-auth documentation.
We’ll also need a route for the login page. It will live at /sign_in and point at UserSessionsCtrl . Here’s my entire config file for reference.
Here’s the controller itself. As of right now it does literally nothing. It just needs to exist.
Make sure to add the filename of your new controller, scripts/controllers/user_sessions.js , to the scripts included in app/index.html .
Finally, we’ll add the sign-in/sign-out links in client/app/index.html .
Next we’ll write a failing integration test for authentication and then make it pass.
4.2 Writing a Failing Integration Test For Sign-In
Writing integration tests for an Angular/Rails SPA is not a trivial matter, and I have a whole separate blog post about it called How to Use RSpec to Test an Angular/Rails Single-Page Application. If you’re actually coding along to this tutorial, I recommend you spin off a new branch and follow that tutorial.
Here’s a spec for successful authentication. You’ll see that this spec uses Factory Girl. I’m going to assume you already know how to use Factory Girl and to set up the factory definition behind :user .
If you run this spec you’ll get an error because Devise will be wanting to send a confirmation email to the user, but your application isn’t properly configured for that. Rather than adjusting our application’s configuration, we’ll just tell Devise not to send the email.
One way of telling Devise not to send the confirmation email is to simply tell Devise the user has already been confirmed. Setting confirmed_at to a particular time will do this. Let’s add a more specific confirmed_user factory:
Change @user = FactoryGirl.create(:user) in authentication_spec.rb to @user = FactoryGirl.create(:confirmed_user) and this particular problem will go away.
Now there’s a different problem. If you run the spec again you’ll get an error that says No route matches [POST] «/api/auth/sign_in» . This is because our devise_token_auth routes need to be defined within the scope of /api , but right now they’re not. To fix that, make your config/routes.rb look like this:
Now that that’s out of the way, there’s another error we’ll have to deal with! This one’s a little more enigmatic. The message is undefined local variable or method mimes_for_respond_to’ for DeviseController:Class . Luckily, I have the solution for you right here. Add this include line to your ApplicationController`:
Now you can finally run your spec and it should pass.
4.3 Making the Failing Spec Pass
Let’s make that failing spec pass. We’ll want a user record to exist in our dev environment, so pop open a rails console and create a user like this:
If you want to, you can navigate to /sign_in , pull up the Chrome developer toolbar (or your browser’s equivalent tool), complete the login form, and watch the request go across the network. The result should be a success.
Run your authentication spec again and it shall pass.
You might notice that if you try to create any additional users beyond that first one, you’ll get an error about a UID. Let’s fix that.
First, a failing spec:
When we run that we get an unpleasant surprise. We get an error that says Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true . So similar to what we saw earlier, Devise is trying in this context to send a confirmation email.
I want to clarify something real quick. Devise’s confirmable module is off be default, and you can optionally turn it on. In devise_token_auth the confirmable module is on by default. If you don’t wish to use the confirmable features, it’s more practical to disable/bypass them than to try to turn the confirmable module off wholesale.
Let’s now add a failing spec that ensures the user model doesn’t try to send an email when saved.
Running this example will still result in a raw error as opposed to the test failure we’d normally want, but that’s okay. It doesn’t matter in this case. Add this line to app/models/user.rb :
If you run the spec again now it will pass. The UID example still fails, as it should. Make it pass by changing the before_save -> < skip_confirmation! >line to this:
Run all your user specs again. Now you’re in business.
4.5 Redirecting After Successful Authentication
Right now the login form technically works but it just kind of weirdly sits there without showing you a new page. Did it work? We need to establish a redirect after successful authentication.
First let’s set up a good page to which to redirect. Change the contents of views/main.html to match the following:
Next we’ll add a failing spec that expects to see the content «This is the home page» after successful login. This text will of course not be present because we haven’t set up the redirect yet. Adjust your authentication spec file to look like this:
We can make this spec pass by adding the following to app/scripts/app.js :
4.4 DRYing Up Our Tests
Our specs pass but they’re full of duplication. Let’s DRY them up. Change your spec to match this:
What’s LoginPage ? It’s a page object whose class is defined like this:
Now our specs should still pass but now they’re neatly DRY.
4.4 Handling Authentication Failure
Right now the UI provides no feedback for an authentication failure. Let’s change this.
First we’ll adjust our authentication_spec.rb to include a spec for invalid login credentials.
Next we’ll add an event listener to UserSessionsCtrl that gets triggered when ng-token-auth issues an auth:login-error event. When this happens we’ll set $scope.error to whatever error was returned by the server (most likely invalid credentials).
And then of course the view will need to display $scope.error somehow.
4.6 Staying Logged In Across Page Refreshes
You might notice that if you refresh the page a few times, you get logged out. I understand that this is due to a problem with token cycling not working properly. You can disable token cycling by uncommenting the following line in config/initializers/devise_token_auth.rb :
I frankly don’t know exactly token cycling hasn’t been working for me, but I’m communicating with the author of devise_token_auth to try to get to the bottom of it. It’s a good idea to cycle tokens for the same reason it’s a good idea to periodically change your password: each time you change your password or token, any previously used password or token becomes unusable to anyone who may have gotten a hold of it.
Remember to restart your Rails server after you disable token cycling.
5.1 Adding The Client-Side Code For The Registration Form
We used the concept of a «user session» resource for authentication, and we can use the concept of a «user registration» resource for registration. Create a new directory in app/views for this new resource.
The new template will look like this. Again, this is lifted from the ng-token-auth docs.
This is the user registrations controller, which for now does nothing:
5.2 Registration Integration Test
Let’s now create a failing spec that tries to register and then, to ensure that registration worked, log in as that just-registered user.
To make this spec pass requires only that we call ng-token-auth ‘s submitRegistration() function, which we do in UserRegistrationsCtrl .
5.3 Logging The User In After Registration
It would of course be convenient to the user if we didn’t require him or her to re-enter his or her email and password to log in after registration, but rather logged the user in automatically. Let’s do that.
Modify your registration spec to match the following:
To make this one pass, we’ll call $auth.submitLogin() after calling $auth.submitRegistration() .
5.4 DRYing Up The Tests
Let’s factor the duplication out of the specs we’ve written.
5.5 Handling Registration Failure
We’ve covered the happy path but not any failure cases. If you try to sign up with, say, a short password or an email address that’s already in use, the registration form apparently simply fails to work. The right thing to do in this case is of course to display an informative error message to the user. Let’s add a scenario for a too-short password.
This is where things get a little bit hairy. If you open your browser’s developer console and then complete the registration form with a too-short password, you’ll see that Devise gives you back an error message in the form of an unwieldy nested array. You can imagine how it would quickly become impractical to somehow parse this nested array based on the errors of the different fields you might anticipate. Let’s not do that. Let’s instead have Devise return a more consumable version of any errors that might be present.
As you may know, the nested-array version of any errors a resource might have can be accessed using resource.errors , and a more API-client-consumable version can be accessed using resource.errors.full_messages . The devise_token_auth gem doesn’t at the time of this writing support returning errors.full_messages , although I understand there are plans to do this. For now, I’ve created a fork of devise_token_auth that does return errors.full_messages . Let’s change our Gemfile to use my fork of the gem:
Remember to bundle install .
If you restart your Rails server and submit the registration form again, you should see in the developer toolbar that Devise now returns a flat, one-dimensional array for the too-short-password error.
We can set $scope.error to the first error Devise returned by adding the following to UserRegistrationsCtrl :
Here’s the full file for reference.
5.5 DRYing Up Our Registration Specs
As always, we’ll want to remove the duplication from our specs. Modify your registration_spec.rb to match the following:
You’ll notice we used another page object here. Here’s what the code looks like for RegistrationPage :
6 Securing Pages and API Endpoints
Authentication of course doesn’t do much good if we’re not restricting access to anything. Let’s secure our client-side pages, then let’s secure the API.
6.1 Securing Pages
If you followed my Angular/Rails tutorial you’ll have a resource called Group present in your app. (If you don’t, create one.) Don’t worry about exactly what a Group represents right now. I just wanted to have some resource that didn’t make sense to access unless the user was logged in, and Group is that resource.
First let’s add a «Groups» link to our main nav.
The Groups view doesn’t need to be much. We just need some way to identify it as being the Groups page.
And in the controller, we don’t even talk to the API. The point is that an unauthenticated user shouldn’t be able to access GroupsCtrl , and whether any API interaction happens there is irrelevant. I’ve hard-coded a couple group names just because.
Now we can add two failing specs: one for accessing the Groups page when signed in, and another for attempting to access the Groups page when not signed in. The spec for authenticated access will of course pass because right now the Groups page is always accessible.
To make the failing spec pass we’ll add a validateUser() call to the groups route.
Your tests should both now be passing. You may also like to temporarily do something to make the spec fail that was never failing, because you of course can’t be sure a test is really testing something unless you’ve seen it fail.
6.2 Securing The API
Right now we can visit http://localhost:3000/api/groups (port 3000 for Rails, not 9000, which would be Grunt) in the browser and see a list of groups from the database. That endpoint is accessible to the world which is not what we want.
All that’s required to fix this is to add a certain before_filter to your GroupsController :
Now when you visit http://localhost:3000 you’ll probably get an error that says undefined method flash’ for # . To fix this, add a config/initializers/devise.rb` with the following content:
Lastly, change the Groups link to only be shown when the user is logged in.
How do you use AngularJS with Ruby on Rails?
a amLfX d QZK lJF b N y voIv y J YUDS e P t TBNW B GnQi r cQN a OvRXL i HU n apx s rqGc
To my personal developing experience! Non! but that is only because I chose to use it in the wrong place and time, so make sure that is not going to happen to you.
Here are some ways that you can use AngularJS with Ruby On Rails:
- Single Page App (SPA), where Rails functions as API and Angular as a receiver on the front end.
- AngularJS as a component UI framework (Maybe I haven’t got the wordi.
Learn to Build Modern Web Apps with AngularJS and Ruby on Rails
Learn how to build an application using AngularJS on the front-end with Ruby on Rails on the back-end.
Help spread the word about this tutorial!
The goal of this tutorial is to guide you through the creation of a Reddit/Hacker News clone using Rails 4 and AngularJS. By completing this tutorial, you will gain a basic understanding of Rails and AngularJS, using Rails to build a JSON REST API that interacts with an AngularJS frontend.
Recommendations for Completing this Tutorial
Throughout the course of this tutorial, links to additional concepts and information will be included. You can use these links as supplementary material which can help you gain insight into the stack and its various components. As always, if you have any questions Google and Stackoverflow are your best bet. If you’re unsure about something specific to this tutorial, feel free to drop us a line at firstname.lastname@example.org
We at Thinkster are firm believers in actually writing code. Therefore we strongly encourage you to type out all the code instead of copy+pasting it.
Before beginning work on any project, it’s usually a good idea to know what you’re building. Below is a basic list of things we want our users to be able to do:
- Create new posts
- View all posts ordered by upvotes
- Add comments about a given post
- View comments for a given post
- Upvote posts and comments
- Create a user authentication system using Devise
Throughout this tutorial we are going to learn, with a practical CRUD example, how to get Angular 2+ (currently Angular 4) integrated into a Ruby on Rails 5.x (currently Rails 5.1.4) web application.
We are going to build, together and step by step, an Angular 2+ with a Rails 5.x backend CRUD (Create Read Update and Delete) example application which demonstrates the essential concepts to integrate the two, client and server side, frameworks.
This tutorial has some primary requirements you need to meet, which are:
- I assume you are comfortable with Ruby on Rails framework.
- I also assume you have some working experience with Angular 2+ (currently Angular 4).
- You have the Ruby language installed on your local development machine (you can use RVM or Ruby Version Manager to easily install it on your machine).
- You also have the NodeJS platform installed on your local machine.
Except for these requirements, you are good to go as we are going to cover everything you need to create a simple (or maybe not) web application with Ruby on Rails in the backend (or server side) and Angular 2+ in the frontend (or the client side).
These are the points we are going to cover in this tutorial:
- How to install Ruby on Rails 5.1.4?
- How to create a RoR 5.1.4 web application?
- Ruby on Rails 5.1.4 API mode.
- How to install Angular 2+ CLI?
- How to create an Angular 2+ project or web app?
- How to integrate Angular 2+ into Ruby on Rails 5.1.4 web app?
- How to communicate between Angular 2+ and Ruby on Rails 5.1.4?
- How to handle CORS issues for local development in Angular 2+?
- How to disable CORS headers for local development in Ruby on Rails 5.1.4?
- How to build an API backend with Ruby on Rails 5?
- How to create Angular 2+ components?
- How to create Angular 2+ providers or services?
- How to add features such as routing and data binding in Angular 2+?
- How to work with Angular 2+ observables and promises?
- How to integrate Bootstrap 4 with Angular 2+ to style the app’s UI?
- How to work with forms?
- How to use ActivatedRoute to get route parameters in Angular 2+?
This article can be cons >
Now lets get started by installing Ruby on Rails 5.1.4.
Installing Ruby on Rails 5.1.4
You might find some problems installing RoR 5.1.4 since it’s the newest and might require a new version of Ruby and some updated gems so i’m going to show you the complete process which I did follow after having some errors when installing RoR 5.1.4 on my local development machine.
First step you better have an updated version of RVM or Ruby Version Manager which is used to install different versions of Ruby on the same machine.
To install or update RVM and get the latest version of Ruby run the following command(s):
The “ —ruby” flag will install the latest stable version of Ruby.
Once this process is finished you can these commands to verify the installed versions of Ruby and gem package manager.
Now you are ready to install Ruby on Rais 5.x on the global gemset but better yet you can also create a project specific gemset and then install RoR 5.
Then use the gem manager to install the newest version of Rails.
Congratulations! you have installed the latest stable version of Ruby on Rails.
Create a Ruby on Rails 5.x API Only App
Open your terminal on MAC or Linux or your command prompt on Windows system then run the following command to create a new API only Rails web application that uses a PosgtreSQL database system (or you can also use MySQL database if you prefer)
Once that finishes, navigate inside the app’s root folder then create the database
Creating Rails API Resources
lets create some resources named Product, Order and Customer:
Then migrate our database
Adding Data for Testing
Let’s create a seed file db/seeds.rb and put some products, orders and customers in it so we can have some data to work with.
Next run the following command to seed the database
Now we are ready to start the Rails server so go ahead and run the following command in your terminal or command prompt:
You should be able to use your web browser to navigate to your newly created Rails app via http://localhost:3000
You can also test your endpoints with the web browser.
Introduction to Angular 2+ (also Angular 4)
An Angular 2+ (currently Angular 4) project contains many files (configuration + source files) and has an opinionated directory structure (At least the project generated with the official Angular CLI) so it needs to have its own separate directory, preferably inside Rails’s project directory.
Installing the Angular 2+ CLI
The Angular 2+ CLI allows you to create an Angular project on the fly without the hassle of Webpack and TypeScript configuration. Before you can use it, it needs to be installed from npm
Again this requires you to have NodeJS and NPM installed on your local development machine.
Generating an Angular 2+ Project
Next navigate inside your working folder
Then generate a new Angular 2+ application
Once that finishes ,navigate inside your app then run ng serve to serve it locally with a live reload local development server.
Using your web browser navigate to http://localhost:4200
That’s it, you are now ready to start developing your front-end app.
Adding Bootstrap 4
Open src/index.html then add Bootstrap 4 files from CDN
Create Angular 2+ Providers/Services
Direct interaction with the remote API backend will take place in providers to encourage separation of concerns so lets create a provider or service that talks to our Rails backend which can be injected in our components via DI or Dependency Injection.
Next you’ll need to import it and add it to the list of providers in app.module.ts
Now lets add the code that talks to our Rails backend remote endpoints.
Open src/app/api.service.ts in your prefered code editor or IDE (I’m using Visual Studio Code which has the best TypeScript support among the other code IDEs) then add:
An import for HttpClient from @angular/common/http
Next declare a variable to hold the address of remote backend
Next inject HttpClient via component constructor:
And finally add the CRUD methods:
Now with these methods we can communicate with our backend.
Create Angular 2+ Components
Now it’s time to create Angular components for creating and listing products, orders and customers.
Using the Angular CLI you can generate these components on the fly by running:
Rails 5.x and Angular 2 Integration
Enable CORS Headers in Ruby on Rails 5.1.4
If you try to communicate with the Rails backend from the Angular app running on diffrent port, you are going to get Not Allowed Access Error:
So we need either to proxy the requests or enable CORS (Cross Origin Resource Sharing) in RoR 5 app.
To enable CORS in Rails 5 follow these steps:
- Uncomment rack-cors in the Gemfile
- Run bundle install
change config/initializers/cors.rb to look like:
You first need to import and add RouterModule to app’s module declarations
Next we’ll need to add the router outlet and links to our main app component. So open src/app/app.component.html then add :
Create a file src/app/product.ts then add the following code.
Create a file src/app/order.ts then add the following code.
Create a file src/app/customer.ts then add the following code.
Working with Forms in Angular 2+?
Before you can use ngModel with forms in Angular 2+ to bind inputs to components’s data variables you need to import the forms module in src/app/app.module.ts and add it to the list of imports
Implementing the CRUD Methods in Components
After adding routing and the API service lets implement the CRUD methods in our previously generated components.
Lets start with ProductListComponent
First open src/app/product-list/product-list.component.html then add an HTML table to list the products:
Next open src/app/product-list/product-list.component.ts then follow these steps:
Import Router, ApiService and Product
Inject Router and ApiService
Declare columns and rows variables which hold the name of the table columns and products data
Add the code to retrieve products in ngOnInit hook
Finally add the delete and update methods
The delete method sends an HTTP DELETE request to RoR 5 backend to delete the resource by its id then filter the rows array to remove the deleted product from the array without refreshing the page.
The update method simply navigates to products/add/:id with the id of the equivalent row.
Now lets see the implementation of ProductAddComponent which is used to add a new product or update an existing product if the id is passed to the route.
Open src/app/product-add/product-add.component.html then add a form:
Next open src/app/product-add/product-add.component.ts and follow these steps:
ActivateRoute is used to get route parameters, in our case we get the id of the product to update.
Inject ApiService and ActivatedRoute via constructor component
Declare a variable to hold the product
When the component is initialized check if the route has an id parameter, if yes send a request to get the product with that id
Finally create onSubmit() method
This method checks of the product has an id if yes it sends a PUT request to update it, if not it sends a POST request to create it.
That’s it, you can do the same with the other components which is left to the reader as an exercise.
In this tutorial, we have seen how to build a simple example CRUD application with Ruby on Rails 5.1.4 in the back-end and Angular 2+ (currently Angular 4) in the front-end. In the next tutorial in these series we are going to see how to implment JWT authentication to our web application. If you have any problem related to this tutorial feel free to drop a comment below, I’ll be more than happy to help you. Thanks for reading and see your in the next tutorial.
Note: We also publish our tutorials on Medium and DEV.to. If you prefer reading in these platforms, you can follow us there to get our newest articles.
You can reach the author via Twitter:
About the author
Get our Learn Angular 8 in 15 Easy Steps ebook in pdf, epub and mobi formats, plus a new Angular 8 tutorial every 3 days.
Online Courses (Affiliate)
If you prefer learning with videos. Check out one of the best Angular courses online
Angular 8 — The Complete Guide (2020+ Edition)
Angular Crash Course for Busy Developers
Setting up an AngularJS and Rails 4.1 Project
Note: Make sure you’re using Rails 4.1!
At my startup Service Route we’ve been building our app on Angular and Rails 4.1. I wanted to start sharing some our experiences on getting these two frameworks working together. All this post is going to cover is how to get them setup. As a plus we’ll also get HTML5 mode routing setup so that Google can index and SEO your angular app! (More info on why this works here)
This tutorial isn’t going to cover Ruby, Rails, or Angular basics. So if you’re completely new to all of those, some things may not make sense, but you should still be able to follow along.
1) Create a new rails app
2) Get the database setup
3) Add two gems to the Gemfile
Bower is a kickass frontend package manager by the same people who did Twitter Bootstrap. It makes installing frontend dependencies a breeze. I was overjoyed when I saw someone had made it into a rake task. To get it up and running you need to make sure you have both Node.js and Bower installed. It takes a couple of minutes at most.
Angular Rails Templates is a helpful gem that makes working with angular templates far easier. It also kills the AJAX requests per template by leverage the template cache. This means less HTTP requests for your user and thus better performance. You’d honestly windup implementing what this package does even if you chose not to use it.
4) Install the gems
5) Initialize Bower
This will give you a bower.json file in your project. What you’ll do here is list the dependencies you need and bower will make them available to rails for you.
6) Open up bower.json and add the following keys/properties to the lib.dependencies:
7) Back in the console, all we need to do now is run a rake task and we’ll have all the dependencies!
This is going to pull in those dependencies and also make the /templates folder available for caching. Speaking of which.
9) Make a folder app/assets/templates/ . It will hold all of your angular templates.
10) If you’ve had the rails server, you need to stop and restart it to make sure those dependencies get added in.
Now we need to configure Rails to let Angular handle routing on the client side end and also allow for HTML5 Mode routing. and thus SEO goodness.
11) Open up config/routes.rb and add the following lines:
This is going to send all incoming requests to our index file and let angular handle them. The second line there allows you to refresh the page on routes and not have Rails confuse a client side refresh with a request to a resource.
Now we need to get the controller configured correctly
12) Open up app/controllers/application_controller.rb and add the following:
This will send all requests to our index.html.erb we’ll be making here in a second. Again, this allows Angular to handle the routing instead of Rails.
13) Create the file app/views/application/index.html.erb and put in the following:
This is where angular will dump its templates.
14) Open up app/views/layouts/application.html.erb and add ng-app=»AngularRails» to the tag:
This is needed to initialize the angular application. Of course nothing will happen yet because we haven’t created any angular code.
You’ll notice that the template url is simply home.html. The way Angular Rails Templates works is that it treats your app/assets/templates/ folder as the root for your angular templates. So if we had a file at app/assets/templates/example/page.html.erb we’d reference it as example/page.html in our templateUrl in Angular. Take note of not including the ERB extension.
Now to create the respective html file and controller.
17) Create the file app/assets/templates/home.html.erb and put in the following:
And everything should be ready to go!
The Git Repo
Here’s what everything should look like at the end:
In actual use
In our stack we’re using Angular UI Router and Restangular instead of the default routing system and $resource. There’s some more configuration required to get them up and working though.
Although there’s nothing over the top complicated here, we couldn’t find any step-by-steps of getting this setup simply. All Rails is going to be doing is acting as an API the majority of the time, but keeping it in the mix gives us other options if we need purely static pages.
If there’s enough interest I’d be more than happy to write about setting up actual REST end points in Rails and connecting them to AngularJS.
As always, tell me if you see any problems or typos!
J Cole Morrison
Cloud Architect, Software Engineer, former Techstars Hackstar, AWS Solutions Architect, and Founder at awsdevops.io
J Cole Morrison
Cloud Architect, Software Engineer, former Techstars Hackstar, AWS Solutions Architect, and Founder at awsdevops.io
The Perfect Foundation for Learning Everything AWS
Learn the core component of every modern infrastructure on AWS: Servers!
Learn the Essential Concepts and Practices of AWS CloudFormation
The best first step into infrastructure as code on AWS!
Learn the Core Concepts of Docker on AWS ECS
Explore all of the key ideas in this 10 part video series!
Code with Jason
Important note: This tutorial no longer works if followed verbatim. I would recommend my more recent updated-for-2020 version.
Why this tutorial exists
I wrote this tutorial because I had a pretty tough time getting Rails and Angular to talk to each other as an SPA. The best resource I could find out there was Ari Lerner’s Riding Rails with AngularJS. I did find that book very helpful and I thought it was really well-done, but it seems to be a little bit out-of-date by now and I couldn’t just plug in its code and have everything work. I had to do a lot of extra Googling and head-scratching to get all the way there. This tutorial is meant to be a supplement to Ari’s book, not a replacement for it. I definitely recommend buying the book because it really is very helpful.
Refreshed for 2015
The sample app
There’s a certain sample app I plan to use throughout AngularOnRails.com called Lunch Hub. The idea with Lunch Hub is that office workers can announce in the AM where they’d like to go for lunch rather than deciding as they gather around the door and waste half their lunch break. Since Lunch Hub is a real project with its own actual production code, I use a different project here called “Fake Lunch Hub.” You can see the Fake Lunch Hub repo here.
Setting up our Rails project
Instead of regular Rails we’re going to use Rails::API. I’ve tried to do Angular projects with full-blown Rails, but I end up with a bunch of unused views, which feels weird. First, if you haven’t already, install Rails::API.
Каков самый чистый способ интеграции Ruby on Rails с AngularJS?
Я создаю приложение Ruby on Rails, и я бы хотел использовать AngularJS в интерфейсе. Я планирую использовать следующую файловую структуру (от здесь) для интерфейса:
У меня есть три основные проблемы:
1 — Я хотел бы, чтобы мое приложение angular прошло через функцию конвейерной обработки Ruby on Rails
2 — Я не хочу разорвать структуру моего приложения angular и переместить его в соответствующую папку ресурсов Rails.
Каков самый чистый способ интеграции этой структуры с моим приложением Ruby on Rails?
Я провел некоторое исследование. Оказывается, самый чистый способ интеграции AngularJS с Ruby on Rails — фактически не интегрировать их в контексте одного приложения Ruby on Rails. Вместо этого лучше всего оставить их полностью разделенными, как предлагал @Minhail.
Как говорит Брэд Карлтон в в этой статье:
Один недостаток, связанный с тем, что весь ваш проект аккуратно заправлен в один из сегодняшние рамки монстров, такие как Rails, Django или MVC, это то, что он может будет очень сложно для стороннего разработчика работать над проектом.
Хотя для опытного Ruby dev для установки rvm, gem установить все зависимости от рубина, обработать собственные расширения и межплатформенные проблемы. Возможно, это не то, что разработчик frontend лучше всего подходит.
Позже в статье он предлагает, чтобы лучшая архитектура заключалась в том, чтобы сохранить интерфейсы и конечные элементы полностью разделенными:
Это также способствует тому, что внешний интерфейс представляет собой приложение первого класса и обеспечить его истинную надежность. Надеюсь, интерфейс разработчику теперь предлагается кодировать неизбежный сценарий, когда бэкэнд опускается.
Что лучше сказать пользователю: «Эй, были некоторые проблемы с сервером прямо сейчас, попробуйте позже» или даже лучше «Поиск у службы, похоже, есть проблемы на данный момент, но вы все еще можете просмотрите свой профиль и текущие проекты».
В соответствии с другой статьей здесь, одностраничное приложение и разработка Api Driven — это два направления веб-разработки в 2015 году. Это факт, который я думаю, сильно поощряет идею фронтального и внутреннего разделения.
Отличный пример этого пошагового пошагового руководства: