Chúng ta đã biết các phương thức helper là các phương thức có thể được gọi trong file View (.html.erb
), trong bài render chúng ta cũng biết là có một cách để “biến” một phương thức bình thường thành một phương thức controller bình thường thành một phương thức helper là khai báo trong phương thức helper_method
.
Trong bài này chúng ta sẽ định nghĩa phương thức helper rõ ràng hơn.
Trong thư mục app của project, có một thư mục có tên là helpers, tất cả các lớp controller được tạo ra sẽ có một file có tên dạng <tên controller>_helper.rb
nằm trong thư mục này. Ngoài ra khi tạo project thì còn có một file nữa là application_helper.rb
. Đây là các file Rails tạo cho chúng ta để định nghĩa các hàm helper.
Chúng ta sẽ viết hàm ẩn thẻ <div id="cart">
nếu giỏ hàng không có sản phẩm nào.
Đầu tiên chúng ta sửa lại file application.html.erb
như sau:
<!DOCTYPE html> <html> <head> <title>Books Store</title> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> </head> <body id="store"> <div id="banner"> <%= image_tag("logo.png") %> <%= @page_title || "Books Store" %> </div> <div id="columns"> <div id="side"> <div id="cart"> <%= hide_cart_if(current_cart.line_items.empty?, :id => "cart") do %> <%= render current_cart %> <% end %> </div> <a href="#">Home</a><br /> <a href="#">FAQ</a><br /> <a href="#">News</a><br /> <a href="#">Contact</a><br /> </div> <div id="main"> <%= yield %> </div> </div> </body> </html>
Chúng ta bọc đoạn <%= render current_cart %>
bằng <%= hide_cart_if() do %>...<% end %>.
Chúng ta truyền vào hàm hide_cart_if
2 tham số, mục đích là để phương thức này biết giỏ hàng có trống không và nếu trống thì ẩn thẻ nào.
Tiếp theo chúng ta định nghĩa phương thức hide_cart_if
trong file application_helper.rb
như sau:
module ApplicationHelper def hide_cart_if(condition, attributes = {}, &block) if condition attributes["style"] = "display:none" end content_tag("div", attributes, &block) end end
Tham số condition
được truyền
vào ở đây cho biết giỏ hàng có trống không. Tham số attributes
là một danh sách các tham số khác, ở trên chúng ta truyền vào là id
có giá trị "cart".
Tham số &block
là đoạn <%= render current_cart %>
.
Nếu condition
là true,
tức là giỏ hàng đúng là trống, thì chúng ta định nghĩa thêm một phần tử trong thuộc tính attributes
có khóa là style
và giá trị là "display:none"
.
Cuối cùng chúng ta gọi phương thức content_tag(),
hàm này nhận vào tên một thẻ, danh sách các thuộc tính và giá trị của tham số đó, và biến &block,
hàm này sẽ bọc những gì trong &block
với tên thẻ và thuộc tính. Tức là bây giờ đoạn code hiển thị giỏ hàng sẽ có dạng như thế này:
. . . <div id="cart"> <div style="display:none"> <%= render current_cart %> </div> </div> . . .
Tức là không hiển thị ra nữa.
Chúng ta cũng sửa lại phương thức destroy
trong lớp CartsController
để khi xóa giỏ hàng thì được trỏ về trang '/'
luôn, không trở lại trang /carts
nữa:
class CartsController < ApplicationController . . . # DELETE /carts/1 # DELETE /carts/1.json def destroy @cart = current_cart @cart.destroy session[:cart_id] = nil respond_to do |format| format.html { redirect_to '/' } format.json { head :no_content } end end . . . end
Vậy là xong.