Ở bài viết này mình sẽ tóm tắt cách dùng Ruby on Rails và Ajax để tạo 1 app có chức năng “thêm vào giỏ hàng” như các shop online. ! 😊😊
Bài viết được viết với mục đích đầu tiên là để chính bản thân đọc lại khi có thời gian nên sẽ rất ngắn gọn và lược đi phần frontend. 😂
Mọi người cùng đọc và góp ý nhé.
Mở đầu
App lần này của mình sẽ là app order sách.
1. Tạo Model và Controller
Tạo Model book
có title
là tên sách và price
là giá sách
rails g model book title:text price:integer
Controller books
với 2 chức năng là create và destroy
rails g controller books create destroy
Model `order` dùng để lưu lại lịch sử order. `quantity` là số lượng mỗi lần order, `total_price` là số tiền mỗi lần order.
Trong table `order` thì `book_id` sẽ là khóa ngoại.
rails g model order quantity:integer total_price:integer book:references
Controller orders
có 2 chức năng là create và destroy
rails g controller orders create destroy
tạo trang homepage cho app qua file index của controller `homes`
rails g controller homes index
Khởi tạo database bằng lệnh migrate
rails db:migrate
2. Tạo tính năng Giỏ Hàng
Tạo book
bằng seed
seed.rb
Book.create(title:"Java", price:50)Book.create(title:"RoRs", price:80)Book.create(title:"C", price:70)
rails db:seed
Config file routes.rb
Rails.application.routes.draw do
get 'books/create'
get 'books/destroy'
resources :orders, only:[:create,:destroy]
resources :homes, only:[:index]
root "homes#index"# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.htmlend
book.rb
classBook<ApplicationRecord
has_many :ordersend
order.rb
classOrder<ApplicationRecord
belongs_to :bookend
Homepage của app sẽ được customize qua file homes/index.html.erb
<h1>Shop</h1>
<% @books.each do |book| %>
<%= book.id %> - <%= book.title %> - <%= book.price %>¥
<%= form_for @order, remote: true do |f| %>
<%= f.hidden_field :book_id, :value => book.id %>
<%= f.number_field :quantity, :value => 1, :min => 1 %>
<%= f.submit "Add to cart" %>
<% end %>
<% end %>
<hr>
<h3>Ordered List</h3>
<div class="reception">
<% @orders.each do |order| %>
<%= render "orders/order", order: order %>
<% end %>
</div>
<h3>Final: <%= Order.sum(:total_price) %></h3>
Danh sách order sẽ được hiện thị bằng file partial orders/_order.html.erb
<%= order.id %> - <%= order.book.title %> -
<%= order.book.price %>¥ x <%= order.quantity %> =
<%= order.total_price %>¥<br>
Config controller homes
và orders
homes_controller.rb
classHomesController<ApplicationControllerdefindex@books=Book.all
@orders=Order.order("created_at DESC")@order=Order.newendend
orders_controller.rb
classOrdersController<ApplicationControllerdefcreate@order=Order.new(order_params)@order.total_price =@order.book.price *@order.quantity
respond_to do|format|if@order.save
format.js {}endendenddefdestroyendprivatedeforder_params
params.require(:order).permit(:book_id,:quantity,:total_price)endend
3. Áp dụng Ajax
Đến đây tính năng Thêm vào giỏ hàng đã cơ bản được hoàn thành. Tiếp theo mình sẽ áp dụng ajax vào app để các thao tác mượt mà hơn. Các bạn có thể xem thêm cách xây dựng 1 app Ajax đơn giản qua bài mình đã viết đây
https://viblo.asia/p/app-ajax-don-gian-trong-rails-bWrZnAmrKxw
Import CDN của ajax vào file `application.html.erb`
<!DOCTYPE html>
<html>
<head>
<title>Testapp</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= yield %>
</body>
</html>
Trong folder app/views/orders, đổi tên file create.html.erb
thành create.js.erb
. Sau mỗi lần bấm button Add to cart
thì file create.js.erb
sẽ được gọi.
$(".reception").prepend("<%= j render @order %>");
Thành quả
Đến đây app đặt sách đơn giản với tính năng thêm vào giỏ hàng đã được hoàn thành. Truy cập vào localhost và xem thành quả nào ^^.
Tổng kết
Bằng cách làm tương tự, ta hoàn toàn có thể làm thêm tính năng xóa sản phẩm và chỉnh sửa số lượng sản phẩm trong ordered list.
Mọi người cùng đọc và góp ý nếu bài viết có thiếu sót nhé. 😊😊
Nguồn: viblo.asia