Web Programming examples

Google Maps,AngularJS

Archives

Ruby on Rails Tutorial follow/unfollow functionality with AngularJS

1)Rails route

$ vi config/routes.rb

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

2)Rails controller

$ vi app/controllers/relationships_controller.rb

class RelationshipsController < ApplicationController
  before_action :signed_in_user

  def create
    remember_token = User.encrypt(cookies[:remember_token])
    current_user ||= User.find_by(remember_token: remember_token)
    @user = User.find(user_params[:id])
    current_user.follow!(@user)
    head :no_content
  end

  def destroy
    remember_token = User.encrypt(cookies[:remember_token])
    current_user ||= User.find_by(remember_token: remember_token)
    @user = User.find(user_params[:id])
    current_user.unfollow!(@user)
    head :no_content
  end

  private
    def user_params
      params.permit(:id)
    end
    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
end

3)AngularJS "relationshipsResource" service

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

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

4)AngularJS controller

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

myModule.controller("UsersShowCtrl", function($scope, $routeParams, userResource, flashService, $filter, micropostsResource, $q, sessionResource, relationshipsResource) {
.....
  $scope.follow = function(id) {
    function success(response) {
      $scope.flg_unfollow = true;
      sessionResource.current_user({}, function(response) {
        flashService.setUser(response);
      });
      $scope.$emit("$routeChangeSuccess");
    }
    function failure(response) {
      console.log("follow error");
    }
    var user_data = {
      id: id
    };
    relationshipsResource.create(user_data, success, failure);
  };

  $scope.unfollow = function(id) {
    relationshipsResource.destroy({ id: id }, function(response) {
      $scope.flg_unfollow = false;
      sessionResource.current_user({}, function(response) {
        flashService.setUser(response);
      });
      $scope.$emit("$routeChangeSuccess");
    });
  };

Ruby on Rails Tutorial show follow/unfollow buttons with AngularJS

1)AngularJS template view

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

<div class="col-xs-6 col-sm-8">
  <div ng-show="!flg_follers && chkSignin() && 
       chkSignin().user.id != user_info.user.id" class="row">
    <div ng-show="flg_unfollow">
      <a class="btn btn-large btn-primary" href="#" 
         ng-click="unfollow(user_info.user.id)">
        Unfollow
      </a>
    </div>
    <div ng-hide="flg_unfollow">
      <a class="btn btn-large btn-primary" href="#" 
        ng-click="follow(user_info.user.id)">follow</a>
    </div>
  </div>

2)AngularJS controller

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

myModule.controller("UsersShowCtrl", function($scope, $routeParams, userResource, flashService, $filter, micropostsResource, $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 chkUnfollow = function() {
    $scope.flg_unfollow = false;
    var deferred = $q.defer();
    deferred.promise.then(function (result) {
      var user_signin = result.user.id;
      for (var i=0; i<=$scope.user_info.followers.length; i++) {
        if ($scope.user_info.followers[i] && $scope.user_info.followers[i].id == user_signin) {
          $scope.flg_unfollow = true;
        }
      }
    },function (reason) {
      console.log("user_signin-Error");
    },function (reason) {
      console.log("user_signin");
    })
    qgetUser(deferred);
  };

  userResource.show({ id: $routeParams.id }, function(response) {
    $scope.user_info = response;
    chkUnfollow();
........
  });

Ruby on Rails Tutorial following and followers pages with AngularJS

(1)Home page

1)follower stats parts

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

<div class="stats">
  <a href="#" ng-click="following()">
    <strong id="following" class="stat">
      {{chkSignin().followed_users.length}}
    </strong>
    following
  </a>
  <a href="#">
    <strong id="followers" class="stat">
      {{chkSignin().followers.length}}
    </strong>
    followers
  </a>
</div>

2)following and followers list parts

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

.....
<div class="col-sm-8">
  <div ng-show="flg_follers" class="row">
    <h1 class="text-center">{{follow_title}}</h1>
    <ul ng-repeat="f_user in f_users" class="users">
      <li><img alt="{{f_user.name}}" src="https://secure.gravatar.com/avatar/{{hash(f_user.email)}}?s=52" />
        <a href="/users/{{f_user.id}}">{{f_user.name}}</a>
      </li>
    </ul>
  </div>
  <h3>Micropost Feed</h3>
.....

3)AngularJS controller

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

myModule.controller("HomeCtrl", function($scope, flashService, micropostsResource, sessionResource, $filter) {
.....
  $scope.chkSignin = function() {
    return flashService.getUser();
  };
.....
  $scope.flg_follers = false;
  $scope.following = function() {
    $scope.flg_follers = true;
    $scope.follow_title = "Following";
    $scope.f_users = $scope.chkSignin().followed_users;
  };
  $scope.followers = function() {
    $scope.flg_follers = true;
    $scope.follow_title = "Followers";
    $scope.f_users = $scope.chkSignin().followers;
  };
  $scope.hash = function(email) {
    return md5(email.toLowerCase());
  };

(2)User Profile page

1)follower stats parts

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

<div class="col-xs-6 col-sm-4">
  <h3>
    <img alt="{{user_info.user.name}}"
         src="{{user_info.gravatar_url}}?s=60"
         class="gravatar" />
    {{user_info.user.name}}
  </h3>
  <span ng-show="flg_follers">
    <a href="#" ng-click="viewProfile()">
      view my profile
    </a>
  </span><br />
  <div class="stats">
    <a href="#" ng-click="following()">
      <strong id="following" class="stat">
        {{user_info.followed_users.length}}
      </strong>
      following
    </a>
    <a href="#" ng-click="followers()">
      <strong id="followers" class="stat">
        {{user_info.followers.length}}
      </strong>
      followers
    </a>
  </div>
</div>

2)following and followers list parts

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

<div class="col-xs-6 col-sm-8">
  <div ng-show="flg_follers" class="row">
    <h3>{{follow_title}}</h3>
    <ul ng-repeat="f_user in f_users" class="users">
      <li><img alt="{{f_user.name}}"
               src="https://secure.gravatar.com/avatar/{{hash(f_user.email)}}?s=52" />
        <a href="/users/{{f_user.id}}">{{f_user.name}}</a>
      </li>
    </ul>
  </div>
  <div ng-hide="flg_follers" class="row">
    <h3>Microposts({{user_info.microposts.length}})</h3>
.......

3)AngularJS controller

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

myModule.controller("UsersShowCtrl", function($scope, $routeParams, userResource, flashService, $filter, micropostsResource, $q) {
.....
  userResource.show({ id: $routeParams.id }, function(response) {
    $scope.user_info = response;
.......
  });
  $scope.flg_follers = false;
  $scope.following = function() {
    $scope.flg_follers = true;
    $scope.follow_title = "Following";
    $scope.f_users = $scope.user_info.followed_users;
  };
  $scope.followers = function() {
    $scope.flg_follers = true;
    $scope.follow_title = "Followers";
    $scope.f_users = $scope.user_info.followers;
  };
  $scope.viewProfile = function() {
    $scope.flg_follers = false;
  };
  $scope.hash = function(email) {
    return md5(email.toLowerCase());
  };

Ruby on Rails Tutorial add follower stats to the profile page

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,
      followed_users: user.followed_users,
      followers:  user.followers
    }
    render json: @user_info
  end

2)AngularJS template view

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

<div class="col-xs-6 col-sm-4">
  <h3>
    <img alt="{{user_info.user.name}}" src="{{user_info.gravatar_url}}" />
      {{user_info.user.name}}
  </h3>
  <div class="stats">
    <a href="#">
      <strong id="following" class="stat">
        {{user_info.followed_users.length}}
      </strong>
      following
    </a>
    <a href="#">
      <strong id="followers" class="stat">
        {{user_info.followers.length}}
      </strong>
      followers
    </a>
  </div>
</div>

Ruby on Rails Tutorial show follower stats with AngularJS

(1)Rails model, association, validation

1)"Relationship" model

$ rails generate model Relationship follower_id:integer followed_id:integer

2)add indices for the relationships table

$ vi db/migrate/…._create_relationships.rb

class CreateRelationships < ActiveRecord::Migration
  def change
    create_table :relationships do |t|
      t.integer :follower_id
      t.integer :followed_id

      t.timestamps
    end
    add_index :relationships, :follower_id
    add_index :relationships, :followed_id
    add_index :relationships, [:follower_id, :followed_id], unique: true
  end
end

3)migrate

$ bundle exec rake db:migrate

4)validation

$ vi app/models/relationship.rb

validates :follower_id, presence: true
validates :followed_id, presence: true

(2)User/followed_users associations

1)"relationship" model

$ vi app/models/relationship.rb

belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"

2)"user" model

$ vi app/models/user.rb

has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed

3)Utility methods for following

$ vi app/models/user.rb

  def following?(other_user)
    relationships.find_by(followed_id: other_user.id)
  end

  def follow!(other_user)
    relationships.create!(followed_id: other_user.id)
  end

  def unfollow!(other_user)
    relationships.find_by(followed_id: other_user.id).destroy
  end

(3)User/followers associations

1)"relationship" model

$ more app/models/relationship.rb

belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"

2)"user" model

$ vi app/models/user.rb

  has_many :reverse_relationships, foreign_key: "followed_id",
                                   class_name:  "Relationship",
                                   dependent:   :destroy
  has_many :followers, through: :reverse_relationships, source: :follower

(3)check by console

1.user instance

> user2=User.find_by(id: 2)
> user6=User.find_by(id: 6)

2."following?"

> user2.following?(user6)
 => nil
> user6.following?(user2)
 => nil

3."follow!"

> user2.follow!(user6)
   (0.2ms)  begin transaction
  SQL (0.3ms)  INSERT INTO "relationships" ("created_at", "followed_id", "follower_id", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", "2015-07-24 08:17:13.716171"], ["followed_id", 6], ["follower_id", 2], ["updated_at", "2015-07-24 08:17:13.716171"]]
   (3.4ms)  commit transaction
 => #<Relationship id: 1, follower_id: 2, followed_id: 6, created_at: "2015-07-24 08:17:13", updated_at: "2015-07-24 08:17:13">

> user6.follow!(user2)

4."relationships", "reverse_relationships" association

> user2.relationships
 => #<ActiveRecord::Associations::CollectionProxy [#<Relationship id: 1, follower_id: 2, followed_id: 6, created_at: "2015-07-24 08:17:13", updated_at: "2015-07-24 08:17:13">]>

> user2.reverse_relationships
  Relationship Load (0.2ms)  SELECT "relationships".* FROM "relationships"  WHERE "relationships"."followed_id" = ?  [["followed_id", 2]]
 => #<ActiveRecord::Associations::CollectionProxy [#<Relationship id: 2, follower_id: 6, followed_id: 2, created_at: "2015-07-24 08:17:54", updated_at: "2015-07-24 08:17:54">]>

> Relationship.all
  Relationship Load (0.2ms)  SELECT "relationships".* FROM "relationships"
 => #<ActiveRecord::Relation [#<Relationship id: 1, follower_id: 2, followed_id: 6, created_at: "2015-07-24 08:17:13", updated_at: "2015-07-24 08:17:13">, #<Relationship id: 2, follower_id: 6, followed_id: 2, created_at: "2015-07-24 08:17:54", updated_at: "2015-07-24 08:17:54">]>

> user2.relationships.find_by(followed_id: user6)
  Relationship Load (0.1ms)  SELECT  "relationships".* FROM "relationships"  WHERE "relationships"."follower_id" = ? AND "relationships"."followed_id" = 6 LIMIT 1  [["follower_id", 2]]
 => #<Relationship id: 1, follower_id: 2, followed_id: 6, created_at: "2015-07-24 08:17:13", updated_at: "2015-07-24 08:17:13">

5."followed_users", "followers" association

> user2.followed_users.count
 => 1
> user2.followers.count
 => 1
> user6.followed_users.count
 => 1
> user6.followers.count
 => 1
> user2.followers.all

> user2.followed_users.all

(4)show following and followers

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,
        feed: user.feed,
        followed_users: user.followed_users,
        followers:  user.followers
      }
      render json: @user_info, status: :accepted, location: user
    else
......
  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,
        feed: current_user.feed,
        followed_users: current_user.followed_users,
        followers:  current_user.followers
      }
      render json: @user_info, status: :accepted
    else
      head :no_content
    end
  end

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">
.........
      <div class="stats">
        <a href="#">
          <strong id="following" class="stat">
            {{chkSignin().followed_users.length}}
          </strong>
          following
        </a>
        <a href="#">
          <strong id="followers" class="stat">
            {{chkSignin().followers.length}}
          </strong>
          followers
        </a>
      </div>

3)css

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

.stats {
  overflow: auto;
  border-top: 1px solid $grayLighter;
  a {
    float: left;
    padding: 0 10px;
    border-left: 1px solid $grayLighter;
    color: gray;
    &:first-child {
      padding-left: 0;
      border: 0;
    }
    &:hover {
      text-decoration: none;
      color: blue;
    }
  }
  strong {
    display: block;
  }
}

Ruby on Rails Tutorial delete micropost with AngularJS

(1)Rails controller

$ vi app/controllers/microposts_controller.rb

  before_action :signed_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy

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

(2)add link to views

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

.....
<small class="text-muted">Posted {{mp.created_at | date:'medium'}}</sm
all>
<span ng-show="chkSignin().user.id == mp.user_id"><a href="" ng-click="delete(mp.id)">delete</a></span>
.....

(3)AngularJS controller

1)User Profile page "UsersShowCtrl" controller

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

myModule.controller("UsersShowCtrl", function($scope, $routeParams, userResource,flashService,micropostsResource) {

  $scope.chkSignin = function() {
    return flashService.getUser();
  };

  $scope.delete = function(id) {
    micropostsResource.destroy({ id: id });
    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);
      flashService.setUser(response);
    });
  };
});

2)Home page "HomeCtrl" controller

  $scope.delete = function(id) {
    micropostsResource.destroy({ id: id });
    sessionResource.current_user({}, function(response) {
      tmp_feed = response.feed;
      $scope.totalitems = tmp_feed.length;
      feed_items = $filter('orderBy')(tmp_feed,'created_at',true);
      $scope.currentitems = feed_items.slice(start,end);
      flashService.setUser(response);
    });
  };

Ruby on Rails Tutorial microposts feed pagination with AngularJS

1)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">
.......
    </div>
    <div class="col-sm-8">
      <h3>Micropost Feed</h3>
      <ol class="microposts">
        <li ng-repeat="mp in currentitems">
...........
        </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>
  </div>

2)AngularJS controller

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

myModule.controller("HomeCtrl", function($scope, flashService, micropostsResource, sessionResource, $filter) {
....
  $scope.submit = function() {
    function success(response) {
      sessionResource.current_user({}, function(response1) {
        var current_user = response1;
        $scope.totalitems = current_user.feed.length;
        feed_items = $filter('orderBy')(current_user.feed,'created_at',true);
        $scope.currentitems = feed_items.slice(start,end);
        flashService.setUser(current_user);
      });
      flashService.push(msg);
      $scope.$emit("$routeChangeSuccess");
    }
    function failure(response) {
........
    }
    micropostsResource.create($scope.micropost, success, failure);
  };
.........
  var feed_items = [];
  $scope.maxsize = 5;
  $scope.itemsperpage = 8;
  $scope.currentpage = 1;
  var start = 0;
  var end = start + $scope.itemsperpage;
  sessionResource.current_user({}, function(response) {
    if (response.feed) {
      var tmp_feed = response.feed;
      $scope.totalitems = tmp_feed.length;
      feed_items = $filter('orderBy')(tmp_feed,'created_at',true);
      $scope.currentitems = feed_items.slice(start,end);
    }
  });
  $scope.$watch('currentpage', function() {
    start = ($scope.currentpage - 1) * $scope.itemsperpage;
    end = start + $scope.itemsperpage;
    $scope.currentitems = feed_items.slice(start,end);
  },true);

});