Tìm kiếm với AngularJS
Bài đăng này đã không được cập nhật trong 4 năm
I-Giới thiệu
Trong bài viết này sẽ truy cập đến chức năng tìm kiếm với AngularJS tích hợp với Rails app.
Ở đây các trường id_numer , name, date_of_birth, place_birth, in_class thuộc bảng Student để hiển thị và đáp ứng với kết quả tìm kiếm.
Đây là kết quả khi đã hoàn thiện.

II-Xây dựng khung
1.Tạo rails app
rails new angular-search-app
rails db:create
rails db:migrate
Notes: Ruby 2.4.0dev, Rails 5.0.0.1
Chúng ta sẽ sử dụng bower để quan lý dependencies của project này. Bower là một package manager của web. Dependencies của project này bao gồm Bootstrap Framework, AngularJS, Angular-resource và Angular-route.
chạy bower intit
Bower sẽ tạo một file bower.json trong root directory của project, nó sẽ hỏi vài câu hỏi như tên của project, tên của tác giả, chi tiết.... Với tên project là angular-search-app thì kết quả của file JSON sẽ như sau:
bower.json
{
  "name": "angular-search-app",
  "authors": [
    "Lim Kimhuor <kimhuorlim@gmail.com>"
  ],
  "description": "Search with AngularJS",
  "main": "",
  "keywords": [
    "AngularJS",
    "rails"
  ],
  "license": "MIT",
  "homepage": "",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ]
}
Để dùng bower với rails app thực hiện bước sau:
- Tạo file 
.bowerrctrong thư mục app 
{
  "directory": "vendor/assets/components"
}
- Thêm thư mục asset cho rails 
config/application.rb 
class Application < Rails::Application
  ...
  config.assets.paths << Rails.root.join('vendor', 'assets', 'components')
  ...
end
- Tiếp theo chạy các dòng lệnh sau:
 
bower install bootstrap --save
bower install angular --save
bower install angular-route --save
bower install angular-resource --save
Với lệnh trên sẽ tạo required dependencies cho project trong directory components và lưu trong file JSON. Nên thêm /vendor/assets/components vào trong .gitignore để không phải up các thư mục đó lên repository Github.
- Thêm require cho javascript rails app
app/assets/javascripts/application.js 
//= require bootstrap/dist/js/bootstrap.min
//= require angular/angular.min
//= require angular-route/angular-route
//= require angular-resource/angular-resource
//= require_tree ./angular
- Phần css 
app/assets/stylesheets/application.scss 
*= require bootstrap/dist/css/bootstrap.min
- Tạo model Student : 
rails g model Student id_number:string, name:string, date_of_birth:datetime, place_of_birth:string, in_class:string 
rails db:migrate
- Phần định tuyến 
config/routes.rb 
root "students#index"
resources :students
- Tạo controller 
rails g controller students 
app/controllers/students_controller.rb
class StudentsController < ApplicationController
  def index
    @students = Student.all
  end
end
- Tạo View: 
app/views/students/index.html.erb 
<div class="row" ng-app="searchApp" ng-controller="SearchController as vm">
  <div class="col-md-8 col-md-offset-2">
    <p id="notice"><%= notice %></p>
    <div class="search_input">
      <h1>Students</h1>
      <div class="row">
        <div class="form-group col-md-4">
          <%= text_field_tag :search_input, nil, placeholder: "Search..", class: "form-control" %>
        </div>
      </div>
    </div>
    <div class="table-responsive">
      <table class="table table-hover table-striped jambo_table">
        <thead>
          <tr>
            <th>ID</th>
            <th>Identity Card</th>
            <th>Name</th>
            <th>Date of birth</th>
            <th>Place</th>
            <th>Class</th>
          </tr>
        </thead>
        <tbody>
          <% @students.each do |student| %>
            <tr>
              <td><%= student.id %></td>
              <td><%= student.id_number %> </td>
              <td><%= student.name %> </td>
              <td><%= student.date_of_birth.strftime("%F") %> </td>
              <td><%= student.place_birth %> </td>
              <td><%= student.place_birth %> </td>
            </tr>
          <% end %>
        </tbody>
      </table>
    </div>
  </div>
</div>
- Tạo dữ liệu để hiển thị 
spec/factories/students.rb 
FactoryGirl.define do
  factory :student do
    id_number {Faker::Number.number(8)}
    name {Faker::Name.name}
    date_of_birth {Faker::Date.between(10.year.ago, Date.today)}
    place_birth {Faker::Address.street_address}
    sequence(:in_class) { |n| "DTTT-#{n}" }
  end
end
lib/tasks/db.rake
namespace :db do
  desc "remake database data"
  task remake_data: :environment do
    Rake::Task["db:migrate:reset"].invoke
    puts "Create 20 students."
    20.times {FactoryGirl.create :student}
    puts "Complete."
  end
end
vào terminal run : rails db:remake_data và rails server
Kết quả hiển thị như sau

2.Khung của angularjs
app/assets/javascript
angular
||- app/
||_||- searchp_app.js
||- contrller/
||_||- search_controller.js
- Build JSON để lấy ở phía angularjs
 
app/controllers/students_controller.rb
class StudentsController < ApplicationController
  def index
    @students = Student.all
    respond_to :html, :json
  end
end
app/views/students/index.json.jbuilder
json.array! @students, partial: 'students/student', as: :student
app/views/students/_student.json.jbuilder
json.extract! student, :id, :id_number, :name, :date_of_birth, :place_birth, :in_class
json.url student_url(student, format: :json)
search_app.js
"use strict";
var searchApp = angular.module("searchApp", ["ngRoute", "ngResource"]);
search_controller.js
searchApp.controller("SearchController", SearchController);
SearchController.$inject = ["$scope", "$http"];
function SearchController($scope, $http) {
  var vm = this;
  $http.get("students.json").success(function(data, status, headers, config) {
    vm.students = data;
  }).error(function(data, status, headers, config) {
    // log error
  });
};
Kết quả của chương trình
- search theo id-card
 

- search theo tên
 

- search theo ngày năm sinh
 

- search theo nơi sinh
 

- search theo lớp học
 

III-Kết luận
Hy vọng bài viết này có thể giúp tăng kiến thức một chút về angularjs với một số phương thức để thực hiện với rails app. Code tham khảo : Github
Tài liệu tham khảo
All rights reserved