Building web apps with Rails4 and AngularJS in 15 minutes

While learning AngularJS to make a single page app using Rails4, I found some good videos and blogs. However, I did not find any simple example for CRUD operations that made me easily understand the integration between Rails4 and AngularJS. So in this tutorial post, I explain how to create basic CRUD operation using Rails4 and AngularJS.

Here is my git repository for the complete code Github

Create rails project


$ rails new rails4_crud_with_angularjs

Create User model


$ rails g model user

file db/migrate/[timestamp]_create_users.rb


class CreateUsers < ActiveRecord::Migration
 def change
   create_table :users do |t|
     t.string :first_name
     t.string :last_name
     t.string :email
     t.string :phone
     t.timestamps
   end
 end
end


$ rake db:migrate

app/model/user.rb


class User < ActiveRecord::Base
 validates :first_name, :last_name, :email, presence: true
end

Create Users controller


$ rails g controller users

Create the CRUD operation in users controller and send JSON response. The code sample is here

Add angular gem

In Gemfile add these two gems.


gem 'angularjs-rails'
gem 'angular-ui-bootstrap-rails' #for bootstrap UI


$ bundle install

Setup layout

Adding ng-app and ng-view indicates that we have an AngularJS app in the page.


<html ng-app="myapplication">
 <head>
   <title>Rails4CrudWithAngularjs</title>
   <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
   <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
   <%= csrf_meta_tags %>
 </head>
 <body>
   <div class="container" ng-view>
     <%= yield %>
   </div>
 </body>
</html>

Create an angular controller

First let’s create a directory for our controllers. You can name it whatever you want.

$ mkdir -p app/assets/javascripts/angular/controllers

Now create users_controllers.js file. Here I have used the same naming convention as Rails.

// app/assets/javascripts/angular/controllers/users_controllers.js
var myApp = angular.module('myapplication', ['ngRoute', 'ngResource']);

‘myapplication’ is ng-app name.

Add Factory

Factory is the angular provider and you can learn more about it here. It basically interacts with the rails server and processes the json response.

myApp.factory('Users', ['$resource',function($resource){
 return $resource('/users.json', {},{
 query: { method: 'GET', isArray: true },
 create: { method: 'POST' }
 })
}]);

myApp.factory('User', ['$resource', function($resource){
 return $resource('/users/:id.json', {}, {
 show: { method: 'GET' },
 update: { method: 'PUT', params: {id: '@id'} },
 delete: { method: 'DELETE', params: {id: '@id'} }
 });
}]);

‘Users’ factory is used for getting the collection of users and creating users. ‘User’ factory is used to get the user details, update the user or delete the user.

Add Routes

Angular routes are used for deep-linking URLs to controllers and views (HTML partials). It watches $location.url() and tries to map the path to an existing route definition.

myApp.config([
 '$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
 $routeProvider.when('/users',{
    templateUrl: '/templates/users/index.html',
    controller: 'UserListCtr'
 });
 $routeProvider.when('/users/new', {
   templateUrl: '/templates/users/new.html',
   controller: 'UserAddCtr'
 });
 $routeProvider.when('/users/:id/edit', {
   templateUrl: '/templates/users/edit.html',
   controller: "UserUpdateCtr"
 });
 $routeProvider.otherwise({
   redirectTo: '/users'
 });
 }
]);

In the code above, I have added the controllers UserListCtr, UserAddCtr, UserUpdateCtr for listing users and to create and update users.

Add Angular templates

Now we need to add templates. I have stored them in public/templates.

If we create a file public/templates/users/index.html with some arbitrary content, we should be able to see it in the browser. Here is a sample template for users.

 CRUD Actions

Now our setup is done and we are ready for processing CRUD operation.

Index Action:

myApp.controller("UserListCtr", ['$scope', '$resource', 'Users', 'User', '$location', function($scope, $resource, Users, User, $location) {
  $scope.users = Users.query(); //it's getting user collection
}]);

‘UserListCtr’ this controller listing users. you can check index.html here I am not explaining index template it’s straight forward angular template, you can read more about it here.

Create Action:

myApp.controller("UserAddCtr", ['$scope', '$resource', 'Users', '$location', function($scope, $resource, Users, $location) {
  $scope.save = function () {
    if ($scope.userForm.$valid){
      Users.create({user: $scope.user}, function(){
      $location.path('/');
    }, function(error){
      console.log(error)
    });
  }
 }
}]);

‘UserAddCtr’ this controller create user. you can check new.html here. Users.create() calling users controller create action. create() action we defined in ‘Users’ factory.

Update Action:

myApp.controller("UserUpdateCtr", ['$scope', '$resource', 'User', '$location', '$routeParams', function($scope, $resource, User, $location, $routeParams) {
   $scope.user = User.get({id: $routeParams.id})
   $scope.update = function(){
     if ($scope.userForm.$valid){
       User.update($scope.user,function(){
         $location.path('/');
       }, function(error) {
         console.log(error)
      });
     }
   };
}]);

‘UserUpdateCtr’ this controller update the user. you can check edit.html here. Users.update() calling users controller update action. update() action we defined in ‘User’ factory.

Delete Action:

For delete user I am not creating separate angular controller. I am writing deleteUser event in ‘UserListCtr’  controller.


myApp.controller("UserListCtr", ['$scope', '$http', '$resource', 'Users', 'User', '$location', function($scope, $http, $resource, Users, User, $location) {

  $scope.users = Users.query();

  $scope.deleteUser = function (userId) {
    if (confirm("Are you sure you want to delete this user?")){
      User.delete({ id: userId }, function(){
        $scope.users = Users.query();   // after delete user get users collection.
        $location.path('/');
      });
    }
  };
}]);

User.delete() calling users controller destroy action. delete() action we defined in ‘User’ factory.

In  public/templates/users/index.html for adding ‘Remove’ link


<a href="" ng-click="deleteUser(user.id)">Remove</a>

Remember href should be blank, if you add href=”#” it will call default route in your application.

I hope this blog helps those are started development in Rails + AngularJS.

Posted in Javascript, Ruby on Rails, Tutorials | Tagged , | Leave a comment

The First-Ever Go Conference in India – GopherConIndia 2015

After the resounding success of GopherCon 2014 in Denver, Co, USA the Go Language Community in India together with the Innovation And Technology Trust (ITT) (a non-profit organization, established to organize and conduct technology conferences in India whose current portfolio includes RubyConf India, GopherCon India and DevOpsDays India) are bringing you the first-ever Go conference in India – GopherConIndia 2015 in Bengaluru (Bangalore) from 19-22 Feb. 2015.

The Indian Go programming community is growing at a dramatic pace. The number of companies utilizing Go, as part of their technology stack, continues to grow steadily.

GopherConIndia 2015

GopherConIndia 2015

Planning and organizing an all India conference is not an easy task but a small team of dedicated volunteers (Ajey Gore, Gautam Rege, Karan Misra, Krishnaprasad Varma, Pravin Mishra, Santosh B Malleshappa, Sathish VJ, Satish Talim – this does not list all of the volunteers, without whom GopherConIndia will not be possible) are already on the job and good progress has already been made. Special mention needs to be made of Brian Ketelsen, Erik St. Martin and Matt Aimonetti who have been guiding and supporting the team of volunteers.

Why Bengaluru (Bangalore)?

Bengaluru, the Silicon Valley of India, is the ideal location for the first-ever Indian Go conference. It has been the host to all the global software companies for many years. It boasts some of the best world-class restaurants and great nightlife to round out your conference experience. No wonder, Bengaluru is termed as the Software and Party Hub of India.

The Venue

Hotel Royal Orchid is approximately less than an hour away from the Kempegowda International Airport and 10 kms from the Central Railway Station. The hotel’s vicinity offers a platter of multiple dining restaurants, electronic stores and shopping malls in the nearby surroundings giving every traveler a remarkable opportunity to enjoy the spirit of Bengaluru city. With all modern facilities, the hotel is a perfect venue for a conference like GopherConIndia.

Dates

GopherConIndia is a single-track event (fully in English) that you don’t want to miss and where everyone gets the opportunity to see the same talks. 20-21 Feb. 2015 are the main days of the conference. A pre-conference party for all the speakers and participants is being planned for 19th Feb. evening and a hack/workshop day for 22nd Feb. 2015.

Estimated Audience

We expect around 300 participants at the conference.

Sponsors and Supporters

The Sponsors and Supporters of the conference realize that this is a great opportunity for them to reach a captive audience of early adopters. Their sponsorship helps keep GopherConIndia affordable and accessible to the widest possible audience.

Please do lend your support to GopherConIndia 2015.

Sponsors and Supporters are lining up! So far we have the following sponsors and supporters and many more are expected soon.

Gold Sponsors

Supporters

Speakers

The CFP is already open and we are getting a lot of awesome talk proposals.

Some of the international speakers who have confirmed their participation so far, are:

Student Scholarships

As part of GopherConIndia’s commitment to encourage students in India to excel in computing and technology, student scholarships are being offered. Female students will be given a preference.

Connect with GopherConIndia

Connect with GopherConIndia to know the latest about the conference:

Be a part of this awesome Go conference and make it a big success.

Posted in Conferences, Go | Tagged , , | 1 Comment

API Throttling on Requests Per Minute

In my previous blog post I have discussed API designing and versioning. Now I am going to build a simple algorithm to restrict API access based on requests per minute using redis

Very often, as an API provider we need to control request traffic based on certain criteria, like account subscription, time interval or requests per day or per month. Redis provides a key expiry functionality based on TTL (time to live) and using this we can implement the requests per minute feature.

# ruby redis client expire method.
redis_client.expire(key, time_to_expire_in_secs)
# i.e
redis_client.expire("1", 60)

Here is the implementation of API request counting store.

  • incr method increments the key and sets the expiry for the key if it’s set for the first time.
  • threshold? method checks the value after incrementing it.
class ApiRpmStore

  TIME_TO_EXPIRE = 60 # 1 min

  class << self
    attr_accessor :redis_client

    def init(config = {})
       self.redis_client = Redis.new(:url => "redis://#{config['host']}:#{config['port']}/#{config['database']}")
    end

    def incr(key)
      val = redis_client.incr(key)
      redis_client.expire(key, TIME_TO_EXPIRE) if val == 1
      val
    end

    def threshold?(key, threshold_value = 0)
      self.incr(key) < threshold_value
    end

  end

end

Test this using the console.

irb> ApiRpmStore.init({'host' => 'localhost', port: 6379, database: 0})

# threshold value is 1 for key 'user-1'
irb> ApiRpmStore.threshold?('user-1', 1) # return true

irb> ApiRpmStore.threshold?('user-1', 1) # return false

Now implement the before action methods in the controller in which we are going to validate for requests per minute. If the requests per minute validation fails, then we return a response ‘422: too many requests’ with some helper url, like the subscription or license page.

class Api::ApiController < ActionController::Base

  private

  def authenticate
    authenticate_or_request_with_http_token do |token, options|
      @user = User.where(api_key: token).first
    end
  end

  def validate_rpm
    if ApiRpmStore.threshold?(@user.id.to_s, @user.request_per_min) # request_per_min is  threshold for
      render json: {help: 'http://mysite.com/plans'}, status: :too_many_requests
      return false
    end
  end
end

This is the events controller on which we are going to throttle the API requests. If you want to apply rate limit to all api then add before_action :validate_rpm to your base api controller (in my case it is the ‘Api::ApiController’ ).

class Api::V1::EventsController < Api::ApiController
  before_action :authenticate
  before_action :validate_rpm

  respond_to :json

  def index
    @events = Event.all
    respond_with @events
  end
end

You can find Rails application code sample on github

Posted in Ruby on Rails | Tagged , | Leave a comment

Real Time notifications using slanger and sidekiq

Gautam Rege:

Did you want Real Time Notifications in your web app? Here is how to do it using Slanger and Sidekiq with a ready to use demo repository.

Originally posted on rails learning:

With the increasing expectation of web-applications, everyone wants real time updates or real time notifications to improve the web portals user experience. Understandably, my project required Real time notifications too. I successfully implemented and deployed on production. During my development I found some interesting gems, javascript libraries that I came across. So I thought it would be helpful if I share my experience. To make it more useful I have created a sample repository for demonstrating Real Time notifications for your further reference.

The AIM: Notify the user with a reminder on specific user defined date and time using Web notifications.

I choose slanger gem. (Recently updated by Jiren to make it compatible with rails4). To make it work, add pusher to rails app and for slanger instead of adding it in rails Gemfile, I created a sub directory called ‘slanger’ in my rails project and added slanger. Now we are done with…

View original 404 more words

Posted in General | Leave a comment

Writing unit tests the right way

Gautam Rege:

Learn to write unit tests in such a way that when they fail, they can point you to the error and not just leave you in the dark!

Originally posted on rails learning:

We all know what unit tests are and which gems we need to use for unit testing. Unit testing means testing a method in isolation. Unit tests are light weight and execute fast when compared to integration tests. You can write unit and integration tests either using rspec or minitest along with any mocking frameworks. Both frameworks have built-in support for mocking frameworks but in rspec they are extracted as a separate gem called rspec-mocks. Here are some pointers

Tests should help in debugging code.

We write tests to check whether we have covered all scenarios for our code. But we forgot to cross-check whether the test cases helps in debugging when an problem raises. Consider the following scenario

1 1 1 1
# app/models/booking.rb

class…

View original 750 more words

Posted in General | Leave a comment

The bidder journey

Reblogged and edited with permission from Doing It Right by Anil Maurya.

It was time for another Rails Rumble event, and I was looking for Ideas what to build. Through one of coding competition I had come across a problem in which you have to write an algorithm to outbid the computer. I am (and have always been) a fan of Computer Games, so why not build a Game based on this problem?

Rails Rumble was the ideal stage – it is a 48 hrs coding competition in which you have to build a Rails application from scratch.

At this point, I knew what to build and which framework to use, but I didn’t know how to build it or even if it’s possible in Rails, so I presented my idea at Open Source Friday. I ran my idea on white board and played a demo with Gautam Rege) on the white board. People liked the idea and suggested some changes and discussed how it can be done. Sanjiv Jha got interested in this game and joined me in this journey.

The day of competition arrived 19 Oct 2013. Sanjiv and I coded 2 days at a stretch. The tech stack we used in Bidder was Ruby 2, Rails 4, Bootstrap 2.3, JQuery 1.9. We used Pusher for broadcasting and receiving real time notifications. Although we didn’t win the competition, we had a great experience.

Bidder didn’t end with the competition, we took it to next level. We open sourced Bidder on github https://github.com/anilmaurya/bidder and asked our colleagues to contribute to it. In one of Open Source Friday we discussed Bidder Issues and took feedback from ruby hackers.

Now, after all this hacking on Bidder it was time to check how Bidder will scale. We organised a Bidder event on Friday evening and invited all rubyist in the city to play Bidder. Of course there was a prize for ultimate winner. Around 25 rubyist played Bidder in this event. Rishi Jain joined in and helped us organizing this event . Pratik Shah won this event beating Sandip Ransing in Final.

This event taught us many things that we had under-estimated like Pusher limitations on requests (we were using Pusher in free mode). This also made us think about cases if the internet is slow or there is no internet; and most important, some serious issues were discovered in this event.

Now we knew that Pusher can’t handle more than 4 users (10 connections) at a time, we had to look for alternatives. Jiren Patel come to rescue us and suggested to use Slanger – an open source implementation of Pusher.

Moving from Pusher to Slanger is really easy if you know how to setup Redis server on cloud. No need to change your code. We hosted Slanger on Amazon EC2(free version) with help from Shailesh Patil. After shifting to Slanger we can easily handle 25 users at time.

Men are mortal. So are ideas. An idea needs propagation as much as a plant needs watering. Otherwise both will wither and die.
B. R. Ambedkar

Ruby Conferences are the best platform to share Ideas among rubyist. RubyConf India 2014 was to be held in about one month, we took the opportunity to share Bidder with every rubyist out there. We got a booth outside Conference hall to showcase our Game. Thanks to Josh Software for sponsoring T-shirts for bidder winner and arranging us booth. This was our Flyer outside Conference Hall.

Bidder at RubyConf India 2014

Bidder at RubyConf India 2014

We hosted 70 knockout Games and distributed 35 T-shirts to winners, response at RubyConf was overwhelming. Pramod Shinde, Aditya Shedge and Siva Gollapalli helped us in organizing this.

So far it has been a great journey and thanks to everyone who joined us in this journey and made it more awesome. We will be looking for more rubyists to join in.

Source code of bidder is on Github.
Play Bidder

Posted in Javascript, Ruby on Rails | Tagged , , | Leave a comment

Experiencing Ruby – the Scottish way

Held in the exquisite Crieff Hydro, Perthshire, this was another example of an exciting professionally organised Ruby Conference. There will always be a lot of information about the talks, so this is more about my experience there!

Perthshire

Perthshire courtesy @b_seven_e

At a conference, it’s very important to ensure that the attendees get to experience the culture in addition to the other aspects of any conference – educating talks and networking. The stay was organised over 4 days, even though the conference was for 2 days. This gave us a lot of time explore the place and also meet other people. I particularly remember that I had every meal with different people!

The weather held out and it was 4 days of excellent weather. The 5k organised was on a bright sunny day and I do regret not participating in it for the petty excuse of not having proper running shoes.

5k run

5k run

Since almost all the attendees were residing in the same hotel, it was not a wonder that the networking was brilliant. I got to meet a LOT of rubyists and considering there were about 200ish people, the faces got familiar over the time we were there.

A unique and refreshing change in the conference structure was that there were workshops being held in parallel with the talks! This seemed to be a pretty successful idea as there is nothing like some hands-on experience at a Ruby conference.

The mix of talks ranged from “non-technical” (Non Violent Communication, Managing Remote Teams and “I don’t know what I am doing”) to “technical talks” (Concurrency, Graph Databases, Elixir) and “Inspiration” (Engineering Delights with cranes and bridges, Office Politics) and even talks involving flying robots! A very good mix for all. Another interesting change that I saw (which also showed the experience of the organisers) was that they took a small poll even before the conference to ensure that they scheduled parallel talks to the audience choice.Evan Phoenix kicked of the conference with an awesome talk on “Reading the Code” and Ron Evans concluded the conference with demos of Ruby in robots. I am looking forward to the videos being published (and not just because I was one of the speakers).

Jess Elridge has started a new conference trend in sketch noting at conferences and they are brilliant.

Sketchnotes

Sketchnotes

The bar conversations were interesting because it seamlessly switched gears from Ruby, country politics and even Rails bashing. As usual the whiskey was flowing and everyone was buying drinks for the others in a group whom they had only just met!

Evan Light organized Artemis in the evening and those wondering what it was should see this (http://vimeo.com/95328559). It was indeed a lot of fun, even to see others play. (I got understandably delayed at the bar!)

Artemis

Artemis

Alan and Paul have ensured that for the seventh time in a row, Scottish Ruby Conference has been a roaring success. I hope it happens again next year and I shall stand by my offer to help Paul and Alan for anything related to making this happen next year.

“A Lagavulin 16 please!”

Posted in Conferences, Ruby | Tagged , , , | Leave a comment