12/08/2018, 14:04

Ajax in Rails

1. Giới thiệu Xin chào tất cả các bạn, hiện nay Ajax được sử dụng rất nhiều trong các ứng dụng web mà mọi người đang nói tới hàng ngày, vậy nó là gì? Bạn có thể hiểu nôm na Ajax là một nhóm các công nghệ phát triển web được sử dụng để tạo các ứng dụng web động hay các ứng dụng giàu tính ...

1. Giới thiệu

Xin chào tất cả các bạn, hiện nay Ajax được sử dụng rất nhiều trong các ứng dụng web mà mọi người đang nói tới hàng ngày, vậy nó là gì?

Bạn có thể hiểu nôm na Ajax là một nhóm các công nghệ phát triển web được sử dụng để tạo các ứng dụng web động hay các ứng dụng giàu tính Internet (rich Internet application).Giống như DHTML, LAMP hay SPA, Ajax tự nó không phải là một công nghệ mà là một thuật ngữ mô tả việc sử dụng kết hợp một nhóm nhiều công nghệ với nhau.

ở bài viết này tôi sẽ chỉ tập trung vào cách viết một ứng dụng sử dụng Ajax trong Rails nên nếu bạn chưa biết Ajax là gì thì xin mời các bạn đọc lại một chút để có cái nhìn sơ sơ về Ajax tại đây hoặc tại đây

2. Tạo một ứng dụng rails

Để có thể bắt đầu tôi sẽ tạo một project mới với rails.

rails new ajax_sample -d mysql

Lệnh trên sẽ tạo ra một ứng dụng có tên là "ajax_sample" có sử dụng hệ quản trị cơ sở dữ liệu là mysql, bây giờ chúng ta cần phải gọi cho thư mục ứng dụng sử dụng với lệnh "cd ajax_sample".

Ở trong file config/database.yml chúng ta cần setting password cho ứng dụng này.

Sau đó cần generate scaffold để tạo ra một đối tượng có đầy đủ các chức năng thêm sửa xóa mà Rails hỗ trợ.

rails generate scaffold Product name:string price:integer

Lệnh trên tạo ra một scaffold hoàn hảo cho việc thêm sửa xóa Product với 2 trường là name và price. Sau đó chúng ta chạy lệnh tạo cơ sở dữ liệu. và tạo file migrate

bundle exec rake db:create
bundle exec rake db:migrate

Bây giờ thì có thể chạy ứng dụng bằng lệnh "rails server" hoặc "rails s"

rails s

3. Ajax in rails

Đến đây thì chúng ta đã có một ứng dụng thêm sửa xóa Product trong Rails. gõ trên trình duyệt http://localhost:3000/products ta vào trang index.

p1.png

ở đây nếu muốn tạo thêm một Product thì ta Click vào nút "New Product" hệ thống sẽ redirect đến một trang tạo mới. Sau khi điền đầy đủ thông tin nhấn submit thì hệ thế sẽ lại redirect về trang index bạn đầu. Như vậy ta thấy việc tạo mới một Product hơi dài dòng một chút. Ta muốn ở ngay trang index có một form tạo mới và sau khi nhập đầy đủ thông tin thì sẽ tạo được luôn một product và thêm luôn vào list prroduct hiển thị. Ajax sẽ giúp chúng ta làm điều này.

đầu tiên ở trang index bạn cân thêm vào một form tạo mới

#app/views/products/index.html.erb

<p id="notice"><%= notice %></p>

<h1>Products</h1>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Price</th>
      <th colspan="3"></th>
    </tr>
  </thead>
  <tbody id="products">
    <%= render @products %>
  </tbody>
</table>

<br>

<%= form_for(@product, remote: true) do |f| %>
  <%= f.label :name %><br>
  <%= f.text_field :name %>
  <%= f.label :price %><br>
  <%= f.text_field :price %>
  <%= f.submit %>
<% end %>

<br>

<%= link_to 'New Product', new_product_path %>

Ở trong form_for chúng ta thêm vào remote: true để rails nhận ra đây là form tạo mới sử dụng ajax. Nó được cung cấp sẵn bởi Rails.Ta thu được màn hình trang index như sau:

p2.png

Ở trong controller chúng ta thêm @product = Product.new vào hàm index và thêm format.js {} vào hàm create. format.js {} sẽ gọi đến file app/views/products/create.js và thực hiện những câu lệnh mà bạn muốn.

#app/controllers/products_controller.rb

class ProductsController < ApplicationController
  before_action :set_product, only: [:show, :edit, :update, :destroy]

  def index
    @products = Product.all
    @product = Product.new
  end
...

  def create
    @product = Product.new(product_params)

    respond_to do |format|
      if @product.save
        format.html { redirect_to @product, notice: 'Product was successfully created.' }
        format.js   {}
        format.json { render :show, status: :created, location: @product }
      else
        format.html { render :new }
        format.json { render json: @product.errors, status: :unprocessable_entity }
      end
    end
  end

Sau đó chúng ta cần tạo thêm file app/views/products/create.js. Trong file này chúng ta phải render ra file app/views/products/_product.html.erb mỗi khi nó được gọi đến. Nội dung của file này sẽ được append trực tiếp vào Dom HTML có Id là products.

#app/views/products/create.js

$("<%= escape_javascript(render @product) %>").appendTo("#products");

#app/views/products/_product.html.erb

<tr>
  <td><%= product.name %></td>
  <td><%= product.price %></td>
  <td><%= link_to 'Show', product %></td>
  <td><%= link_to 'Edit', edit_product_path(product) %></td>
  <td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>

Như vậy đến đây chúng ta đã hoàn thành xong việc tạo một Product sử dụng Ajax. Chúng ta có thể tạo một Product mới một cách dễ dàng mà không cần redirect tới bất kì trang nào khác.

3.png

tiếp theo chúng ta tạo thêm chức năng xóa Product sử dụng Ajax.

Ở trong file app/views/products/_product.html.erb chúng ta cần thêm remote: true và class: "destroy-product" trong link_to 'Destroy'

#app/views/products/_product.html.erb

<tr>
  <td><%= product.name %></td>
  <td><%= product.price %></td>
  <td><%= link_to 'Show', product %></td>
  <td><%= link_to 'Edit', edit_product_path(product) %></td>
  <td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' }, remote: :true, class: "destroy-product" %></td>
</tr>

Trong file app/controllers/products_controller.rb ta cần thêm format.js { render layout: false } trong hàm destroy.

#app/controllers/products_controller.rb

  def destroy
    @product.destroy
    respond_to do |format|
      format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
      format.json { head :no_content }
      format.js   { render layout: false }
    end
  end
...

format.js này sẽ gọi đến file app/views/products/destroy.js.erb nên chúng ta cần tạo thêm file này với nội dung như sau.

#app/views/products/destroy.js.erb

$('.destroy-product').bind('ajax:success', function() {
   $(this).closest('tr').fadeOut();
});

những dòng trên thực hiện việc xóa đi từ từ dòng trong bảng hiển thị Product.

4.png

Chúng ta có thể xóa Product mà không cần phải reload lại trang. điều này đặc biệt có ý nghĩa trong những hệ thống lớn, nó sẽ tiết kiệm được một lượng lớn băng thông và cải thiện hiệu năng của hệ thống.

Đến đây tôi đã giới thiệu tới các bạn xong toàn bộ ví dụ tạo một ứng dụng đơn giản sử dụng Ajax trong Rails.

4. Lời kết và tài liệu tham khảo

Tất cả source code của toàn bộ bài viết được upload tại đây:

>>Source Code

http://guides.rubyonrails.org/working_with_javascript_in_rails.html#an-introduction-to-ajax https://www.tutorialspoint.com/ruby-on-rails/rails-and-ajax.htm

Cảm ơn bạn đã đọc bài viết của tôi, mọi đóng góp và thắc mắc các bạn vui lòng comment xuống bên dưới. Chúc các bạn thành công!

-- Hoàng Văn Trình AS Việt Nhật K55 Đại học Bách Khoa Hà Nội

0