Web Programming examples

Google Maps,AngularJS

Category Archives: Ruby on Rails

Ruby on Rails Tutorial create micropost with AngularJS

1)Rails route

$ vi config/routes.rb

match '/app/microposts', to: 'microposts#create',  via: 'post'
match '/app/microposts', to: 'microposts#destroy', via: 'delete'

2)Rails controller

$ vi app/controllers/microposts_controller.rb

class MicropostsController < ApplicationController
  def create
    remember_token = User.encrypt(cookies[:remember_token])
    current_user ||= User.find_by(remember_token: remember_token)
    micropost = current_user.microposts.build(micropost_params)
    if micropost.save
      render json: micropost, status: :created
    else
      render json: micropost.errors, status: :unprocessable_entity
    end
  end

  private
    def micropost_params
      params.require(:micropost).permit(:content)
    end
end

3)AngularJS service

$ vi app/assets/javascripts/mymodule.js.erb

myModule.factory("micropostsResource", function($resource) {
  return $resource("/app/microposts",{},
    {
      'create':  { method: 'POST' },
      'destroy': { method: 'DELETE' }
    }
  );
});

4)AngularJS controller

$ vi app/assets/javascripts/mymodule.js.erb

myModule.controller("HomeCtrl", function($scope, flashService, micropostsResource, sessionResource) {
  $scope.micropost = {};
  $scope.micropost.content = "Compose new micropost...";
  var msg = "Micropost created!";
  $scope.submit = function() {
    function success(response) {
      sessionResource.current_user({}, function(response1) {
        var current_user = response1;
        flashService.setUser(current_user);
      });
      flashService.push(msg);
      $scope.$emit("$routeChangeSuccess");
    }
    function failure(response) {
    }
    micropostsResource.create($scope.micropost, success, failure);
  };
  $scope.getMessage = function() {
    return flashService.get();
  };
});

myModule.factory("flashService", function ($rootScope, $timeout) {
  var queue = [];
  var currentMessage = "";
.......
  $rootScope.$on("$routeChangeSuccess", function() {
    currentMessage = queue.shift() || "";
  });

  return {
    push: function (msg) {
      queue.push(msg);
    },
......

5)AngularJS template view

$ vi app/assets/templates/static_pages/home.html.erb

<div ng-controller="HomeCtrl">
  <div ng-show="chkSignin().user.id > 0" class="row">
    <div class="bg-warning" ng-show="getMessage()">
      <p>{{getMessage()}}</p>
    </div>
    <div class="col-sm-4">
..........
      <form name="micropostForm" ng-submit="submit()" novalidate>
        <textarea name="content" class="form-control"
                  ng-model="micropost.content" rows="3" required>
        </textarea>
        <button type="submit" ng-disabled="micropostForm.$invalid"
                class="btn btn-large btn-primary">Post
        </button>
      </form>

Ruby on Rails Tutorial adding microposts count and gravatar to home page with AngularJS

1)Rails controller

$ vi app/controllers/sessions_controller.rb

  def create
    user = User.find_by(email: session_params[:email].downcase)
    if user && user.authenticate(session_params[:password])
      remember_token = User.new_remember_token
      cookies.permanent[:remember_token] = remember_token
      user.update_attribute(:remember_token, User.encrypt(remember_token))
      gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
      microposts = user.microposts
      @user_info = {
        user: user,
        gravatar_url: "https://secure.gravatar.com/avatar/#{gravatar_id}",
        microposts: microposts
      }
      render json: @user_info, status: :accepted, location: user
    else
      msg = {"password" => ["Invalid email/password combination"]}
      render json: msg, status: :unprocessable_entity
    end
  end

  def current_user
    remember_token = User.encrypt(cookies[:remember_token])
    current_user ||= User.find_by(remember_token: remember_token)
    if current_user
      gravatar_id = Digest::MD5::hexdigest(current_user.email.downcase)
      microposts = current_user.microposts
      @user_info = {
        user: current_user,
        gravatar_url: "https://secure.gravatar.com/avatar/#{gravatar_id}",
        microposts: microposts
      }
      render json: @user_info, status: :accepted
    else
      head :no_content
    end
  end

2)AngularJS "UsersNewCtrl" controller

myModule.controller("UsersNewCtrl", function($scope, userResource, $location, flashService, $routeParams, sessionResource, $q) {
.....
  $scope.submit = function() {
    function success(response) {
.........
      var user_info = { 
        user: response,
        gravatar_url: "https://secure.gravatar.com/avatar/" + md5(response.email.toLowerCase())
      };
      flashService.setUser(user_info);
      $location.path("/users/" + response.id);
    }

3)AngularJS "HomeCtrl" controller and template view

1.AngularJS "HomeCtrl" controller

$ vi app/assets/javascripts/mymodule.js.erb

myModule.controller("HomeCtrl", function($scope,flashService) {
  $scope.chkSignin = function() {
    return flashService.getUser();
  };
});

2.AngularJS template view

$ vi app/assets/templates/static_pages/home.html.erb

<div ng-controller="HomeCtrl">
  <div ng-show="chkSignin().user.id > 0" class="row">
    <div class="col-sm-4">
      <a href="/users/{{chkSignin().user.id}}">
        <img alt="{{chkSignin().user.name}}"
             src="{{chkSignin().gravatar_url}}?s=60"
             class="gravatar"
        />
      </a>
      <h4>{{chkSignin().user.name}}</h4>
      <span><a href="/users/{{chkSignin().user.id}}">view my profile</a></span><br />
      <ng-pluralize count="chkSignin().microposts.length"
                    when="{'0': '0 micropost',
                           'one': '1 micropost',
                           'other': '{} microposts'}">
      </ng-pluralize>
    </div>
  </div>
  <div ng-hide="chkSignin().user.id > 0">
    <div class="jumbotron">
      <h1>Welcome to the Sample App</h1>
.........

Ruby on Rails Tutorial microposts pagination with AngularJS

1)AngularJS template view

$ vi app/assets/templates/users/show.html.erb

<div ng-controller="UsersShowCtrl" class="container">
.........
    <div class="col-xs-6 col-sm-8">
      <h3>Microposts({{user_info.microposts.length}})</h3>
      <ol class="microposts">
        <li ng-repeat="mp in currentitems">
          <div>{{mp.content}}</div>
          <small class="text-muted">Posted {{mp.created_at | date:'medium'}}</small>
        </li>
      </ol>
      <pagination total-items="totalitems"
                  ng-model="currentpage"
                  max-size="maxsize"
                  items-per-page="itemsperpage"
                  class="pagination-sm"
                  previous-text="Previous"
                  next-text="Next"
                  first-text="First"
                  last-text="Last"
                  boundary-links="true">
      </pagination>
    </div>

2)AngularJS controller

$ vi app/assets/javascripts/mymodule.js.erb

myModule.controller("UsersShowCtrl", function($scope, $routeParams, userResource, flashService, $filter) {
  $scope.maxsize = 5;
  $scope.itemsperpage = 3;
  $scope.currentpage = 1;
  var microposts = [];
  var start = 0;
  var end = start + $scope.itemsperpage;
  userResource.show({ id: $routeParams.id }, function(response) {
    $scope.user_info = response;
    $scope.totalitems = $scope.user_info.microposts.length;
    microposts = $filter('orderBy')($scope.user_info.microposts,'created_at',true);
    $scope.currentitems = microposts.slice(start,end);

    $scope.$watch('currentpage', function() {
      start = ($scope.currentpage - 1) * $scope.itemsperpage;
      end = start + $scope.itemsperpage;
      $scope.currentitems = microposts.slice(start,end);
    },true);
  });

Ruby on Rails Tutorial showing microposts with AngularJS

1)Rails controller

$ vi app/controllers/users_controller.rb

  def show
    user = User.find(params[:id])
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    microposts = user.microposts
    @user_info = {
      user: user,
      gravatar_url: "https://secure.gravatar.com/avatar/#{gravatar_id}",
      microposts: microposts
    }
    render json: @user_info
  end

2)AngularJS template view

$ vi app/assets/templates/users/show.html.erb

<div ng-controller="UsersShowCtrl">
  <div class="row">
.......
    <div class="col-xs-6 col-sm-8">
      <h3>Microposts({{user_info.microposts.length}})</h3>
      <ol class="microposts">
        <li ng-repeat="mp in user_info.microposts">
          <div>{{mp.content}}</div>
          <small class="text-muted">Posted {{mp.created_at | date:'medium'}}</small>
        </li>
      </ol>
    </div>
  </div>
</div>

3)css

$ vi app/assets/stylesheets/custom.css.scss

/* microposts */

.microposts {
  list-style: none;
  margin: 10px 0 0 0;

  li {
    padding: 10px 0;
    border-top: 1px solid #e8e8e8;
  }
}

Ruby on Rails Tutorial micropost model,associations

(1)micropost model

1.basic model

$ rails generate model Micropost content:string user_id:integer

2.add index

$ vi db/migrate/…._create_microposts.rb

class CreateMicroposts < ActiveRecord::Migration
  def change
    create_table :microposts do |t|
      t.string :content
      t.integer :user_id

      t.timestamps
    end
    add_index :microposts, [:user_id, :created_at]
  end
end

3.migrate

$ bundle exec rake db:migrate

4.micropost validations

$ vi app/models/micropost.rb

class Micropost < ActiveRecord::Base
  validates :content, presence: true, length: { maximum: 140 }
  validates :user_id, presence: true
end

(2)User/Micropost associations

1. Micropost model

$ vi app/models/micropost.rb

class Micropost < ActiveRecord::Base
  belongs_to :user
......

2. User model

$ vi app/models/user.rb

class User < ActiveRecord::Base
  has_many :microposts, dependent: :destroy
.....

3. check

$ rails console

2.0.0p247 :001 > micropost = Micropost.create(content: "Test #1", user_id: 10)

2.0.0p247 :002 > micropost = Micropost.create(content: "Test #2", user_id: 10)

2.0.0p247 :003 > micropost=Micropost.find_by(user_id: 10)
  Micropost Load (0.3ms)  SELECT  "microposts".* FROM "microposts"  WHERE "microposts"."user_id" = 10 LIMIT 1
 => #<Micropost id: 1, content: "Test #1", user_id: 10, created_at: "2015-07-21 00:00:50", updated_at: "2015-07-21 00:00:50">

2.0.0p247 :004 > micropost.user
  User Load (0.1ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = ? LIMIT 1  [["id", 10]]
 => #<User id: 10, name: "testuser10", email: "test10@example.com", created_at: "2015-07-13 08:45:35", updated_at: "2015-07-20 08:30:47", password_digest: "$2a$10$BLM/nUrE1wptItRDOkKm4OynNZ718yjoDnnIBUkWL0s…", remember_token: "48c3edd244e42156c38e89fca5fe5616c5cfcce1", admin: false>

Ruby on Rails Tutorial delete user with AngularJS

(1)Administrative users

1)adds the admin column to the users table

$ rails generate migration add_admin_to_users admin:boolean

$ vi db/migrate/…._add_admin_to_users.rb

class AddAdminToUsers < ActiveRecord::Migration
  def change
    add_column :users, :admin, :boolean, default: false
  end
end

2)migrate

$ bundle exec rake db:migrate

3)sample data

$ rails console

2.0.0p247 :001 > adminuser = User.create(name: "admin", email: "admin@example.com", password: "xxxxx", password_confirmation: "xxxxx",admin: true)
2.0.0p247 :002 > adminuser.admin?
 => true

(2)Rails controller

1)destroy action

$ vi app/controllers/users_controller.rb

  def destroy
    User.find(params[:id]).destroy
    head :no_content
  end

2)users have to be logged in to delete users

$ vi app/controllers/users_controller.rb

before_action :signed_in_user, only: [:index,:update,:destroy]

3)only admins can delete users

$ vi app/controllers/users_controller.rb

  before_action :admin_user,     only: :destroy
......
  private
........
    def admin_user
      remember_token = User.encrypt(cookies[:remember_token])
      current_user ||= User.find_by(remember_token: remember_token)
      render status: :unauthorized unless current_user.admin?
    end

(3)AngularJS template view

$ vi app/assets/templates/users/index.html.erb

<ul ng-repeat="user in currentitems" class="users">
  <li>
    <img alt="{{user.name}}" src="https://secure.gravatar.com/avatar/{{hash(user.email)}}?s=52" />
    <a href="/users/{{user.id}}">{{user.name}}</a>
    <a ng-show="{{ychkAdmin}}" href="" ng-click="delete(user.id)">| delete</a>
  </li>
</ul>

(4)AngularJS controller

$ vi app/assets/javascripts/mymodule.js.erb

myModule.controller("UsersIndexCtrl", function($scope, userResource, flashService, $location, sessionResource, $q) {
......
  var deferred = $q.defer();
  deferred.promise.then(function (result) {
    var user_info = result;
    if (user_info.user.id > 0) {
      $scope.chkAdmin = user_info.user.admin;
      userResource.index({}, function(response) {
        $scope.users = response;
        $scope.totalitems = $scope.users.length;
        $scope.currentitems = $scope.users.slice(start,end);

        $scope.$watch('currentpage', function() {
          start = ($scope.currentpage - 1) * $scope.itemsperpage;
          end = start + $scope.itemsperpage;
          $scope.currentitems = $scope.users.slice(start,end);
        },true);
      });
    } else {
      $location.path("/signin");
    }
  },function (reason) {
    console.log("qgetUser-Error");
  })
  qgetUser (deferred);
......
  $scope.delete = function(id) {
    userResource.destroy({ id: id });
    userResource.index({}, function(response) {
      $scope.users = response;
      $scope.totalitems = $scope.users.length;
      $scope.currentitems = $scope.users.slice(start,end);
    });
  };
});

Ruby on Rails Tutorial paginate the users with AngularJS

ref.
http://angular-ui.github.io/bootstrap/#/pagination
http://getbootstrap.com/components/#pagination

1)AngularJS template view

$ vi app/assets/templates/users/index.html.erb

<div ng-controller="UsersIndexCtrl">
  <h1 class="text-center">All users</h1>
  <pagination total-items="totalitems"
              ng-model="currentpage"
              max-size="maxsize"
              items-per-page="itemsperpage"
              class="pagination-sm"
              previous-text="Previous"
              next-text="Next"
              first-text="First"
              last-text="Last"
              boundary-links="true">
  </pagination><br />
  <ul ng-repeat="user in currentitems" class="users">
    <li><img alt="{{user.name}}" src="https://secure.gravatar.com/avatar/{{hash(user.email)}}?s=52" />
      <a href="/users/{{user.id}}">{{user.name}}</a>
    </li>
  </ul>
  <pagination total-items="totalitems"
              ng-model="currentpage"
              max-size="maxsize"
              items-per-page="itemsperpage"
              class="pagination-sm"
              previous-text="Previous"
              next-text="Next"
              first-text="First"
              last-text="Last"
              boundary-links="true"
              rotate="false">
  </pagination>
</div>

2)AngularJS controller

myModule.controller("UsersIndexCtrl", function($scope, userResource, flashService, $location, sessionResource, $q) {
  $scope.maxsize = 5;
  $scope.itemsperpage = 3;
  $scope.currentpage = 1;
  var start = 0;
  var end = start + $scope.itemsperpage;

  var qgetUser = function(deferred) {
.........
  }
  var deferred = $q.defer();
  deferred.promise.then(function (result) {
    var user_info = result;
    if (user_info.user.id > 0) {
      userResource.index({}, function(response) {
        $scope.users = response;
        $scope.totalitems = $scope.users.length;
        $scope.currentitems = $scope.users.slice(start,end);

        $scope.$watch('currentpage', function() {
          start = ($scope.currentpage - 1) * $scope.itemsperpage;
          end = start + $scope.itemsperpage;
          $scope.currentitems = $scope.users.slice(start,end);
        },true);
      });
    } else {
      $location.path("/signin");
    }
  },function (reason) {
    console.log("qgetUser-Error");
  })
  qgetUser (deferred);

  $scope.hash = function(email) {
    return md5(email.toLowerCase());
  };
});

Ruby on Rails Tutorial users index with AngularJS

1)Rails controller

$ vi app/controllers/users_controller.rb

class UsersController < ApplicationController
  before_action :signed_in_user, only: [:index, :update]

  def index
    @users = User.all
    render json: @users
  end

2)AngularJS route

$ vi app/assets/javascripts/mymodule.js.erb

.when("/users", {
 templateUrl: "<%= asset_path('users/index.html.erb') %>"
 })

3)install JavaScript-MD5 to display gravatar

1.download
https://github.com/blueimp/JavaScript-MD5

2.deploy
vendor/assets/javascripts/

3.include

$ vi app/assets/javascripts/application.js

//= require md5.min

4)AngularJS template view

$ vi app/assets/templates/users/index.html.erb

<div ng-controller="UsersIndexCtrl">
  <h1 class="text-center">All users</h1>
  <ul ng-repeat="user in users" class="users">
    <li><img alt="{{user.name}}" src="https://secure.gravatar.com/avatar/{{hash(user.email)}}?s=52" />
      <a href="/users/{{user.id}}">{{user.name}}</a>
    </li>
  </ul>
</div>

5)css

$ vi app/assets/stylesheets/custom.css.scss

$grayLighter: rgb(238, 238, 238);

/* users index */

.users {
  list-style: none;
  margin: 0;
  li {
    overflow: auto;
    padding: 10px 0;
    border-top: 1px solid $grayLighter;
    &:last-child {
      border-bottom: 1px solid $grayLighter;
    }
  }
}

6)AngularJS controller

$ vi app/assets/javascripts/mymodule.js.erb

myModule.controller("UsersIndexCtrl", function($scope, userResource, flashService, $location, sessionResource, $q) {
  var qgetUser = function(deferred) {
    if (flashService.getUser()) {
      var quser_info = flashService.getUser();
      deferred.resolve(quser_info);
    } else {
      sessionResource.current_user({}, function(response) {
        if (response.user.id) {
          var quser_info = response;
        } else {
          var quser_info = { user: {id: 0} };
        }
        flashService.setUser(quser_info);
        deferred.resolve(quser_info);
      });
    }
  }
  var deferred = $q.defer();
  deferred.promise.then(function (result) {
    var user_info = result;
    if (user_info.user.id > 0) {
      $scope.users = userResource.index();
    } else {
      $location.path("/signin");
    }
  },function (reason) {
    console.log("qgetUser-Error");
  })
  qgetUser (deferred);

$ vi app/views/layouts/_header.html.erb

  $scope.hash = function(email) {
    return md5(email.toLowerCase());
  };
});

7)add link to navigation menu

<li ng-show="chkSignin().user.id > 0"><%= link_to "Users", "/users" %></li>

Ruby on Rails Tutorial update require the right user

1)Rails controller

$ vi app/controllers/users_controller.rb

class UsersController < ApplicationController
  before_action :correct_user,   only: [:update]

  private
    def correct_user
      user = User.find(params[:id])
      remember_token = User.encrypt(cookies[:remember_token])
      current_user ||= User.find_by(remember_token: remember_token)
      if current_user != user
        render status: :unauthorized
      end
    end

2)AngularJS controller

$ vi app/assets/javascripts/mymodule.js.erb

myModule.controller("UsersNewCtrl", function($scope, userResource, $location, flashService, $routeParams, sessionResource, $q) {
......
......
  var deferred = $q.defer();
  deferred.promise.then(function (result) {
    var user_info = result;
    if ($routeParams.id) {
      if (user_info.user.id == $routeParams.id) {
.........

Ruby on Rails Tutorial update require a logged-in user

(1)Rails controller

$ vi app/controllers/users_controller.rb

class UsersController < ApplicationController
  before_action :signed_in_user, only: [:update]

  private
    def signed_in_user
      remember_token = User.encrypt(cookies[:remember_token])
      current_user ||= User.find_by(remember_token: remember_token)
      if current_user.nil?
        render status: :unauthorized
      end
    end

(2)AngularJS controller

$ vi app/assets/javascripts/mymodule.js.erb

myModule.controller("UsersNewCtrl", function($scope, userResource, $location, flashService, $routeParams) {
  if ($routeParams.id) {
    if (flashService.getUser().user.id > 0 ) {
      var msg = "Profile updated";
      $scope.title = "Update your profile";
      $scope.btn_name = "Save changes";
      userResource.show({ id: $routeParams.id }, function(user_info) {
        $scope.user = user_info.user;
        $scope.gravatar_url = user_info.gravatar_url;
      })
    } else {
      var msg = "Please sign in.";
      flashService.push(msg);
      $location.path("/signin");
    }
  } else {

.........

(3)flash message

1)AngularJS template view

$ vi app/assets/templates/sessions/new.html.erb

<div ng-controller="SessionsNewCtrl" class="row">
  <div class="col-md-6 col-md-offset-3">
    <div class="bg-warning" ng-show="getMessage()">
      <p>{{getMessage()}}</p>
    </div>
    <h1 class="text-center">Sign in</h1>

2)AngularJS controller

$ vi app/assets/javascripts/mymodule.js.erb

myModule.controller("SessionsNewCtrl", function($scope, sessionResource,$location,flashService) {
  $scope.getMessage = function() {
    return flashService.get();
  };
});

(4)countermeasure of the browser reload

myModule.controller("UsersNewCtrl", function($scope, userResource, $location, flashService, $routeParams, sessionResource, $q) {
  var msg = "";
  var qgetUser = function(deferred) {
    if (flashService.getUser()) {
      var quser_info = flashService.getUser();
      deferred.resolve(quser_info);
    } else {
      sessionResource.current_user({}, function(response) {
        if (response.user.id) {
          var quser_info = response;
        } else {
          var quser_info = { user: {id: 0} };
        }
        flashService.setUser(quser_info);
        deferred.resolve(quser_info);
      });
    }
  }
  var deferred = $q.defer();
  deferred.promise.then(function (result) {
    var user_info = result;
    if ($routeParams.id) {
      if (user_info.user.id > 0) {
        msg = "Profile updated";
        $scope.title = "Update your profile";
        $scope.btn_name = "Save changes";
        userResource.show({ id: $routeParams.id }, function(user_info) {
          $scope.user = user_info.user;
          $scope.gravatar_url = user_info.gravatar_url;
        })
      } else {
        msg = "Please sign in.";
        flashService.push(msg);
        $location.path("/signin");
      }
    } else {
      msg = "Welcome to the Sample App!";
      $scope.title = "Sing up";
      $scope.btn_name = "Create my account";
      $scope.user = new userResource();
    }
  },function (reason) {
    console.log("qgetUser-Error");
  })
  qgetUser (deferred);