Hệ thống thẻ (tag) là gì?
Hệ thống thẻ cho phép bạn thêm nhãn (thẻ) vào các mục để tổ chức và tìm kiếm chúng một cách dễ dàng.
Ưu điểm
- Dễ dàng phân loại các mục. Ví dụ: Trên một trang web công thức nấu ăn, bạn có thể gắn thẻ các công thức là "ăn chay", "nhanh", "Ý", cho phép người dùng nhanh chóng tìm thấy các công thức phù hợp với sở thích của họ.
- Linh hoạt - bạn có thể sử dụng nhiều thẻ. Ví dụ: Một bức ảnh trên Instagram có thể có các thẻ như #hoànghôn, #biển, #kỳnghỉ, #giađình, tất cả mô tả các khía cạnh khác nhau của cùng một hình ảnh.
- Giúp tìm kiếm và lọc. Ví dụ: Trên một trang web thương mại điện tử, bạn có thể tìm kiếm "áo khoác da màu đỏ" và hệ thống sẽ tìm các mục được gắn thẻ với cả "đỏ" và "da" trong danh mục "áo khoác".
Nhược điểm
- Có thể trở nên lộn xộn nếu sử dụng quá nhiều thẻ. Ví dụ: Một bài đăng blog được gắn thẻ với #côngnghệ, #thiếtbị, #điệnthoại thôngminh, #android, #samsung, #galaxys21, #đánhgiá có thể gây choáng ngợp và kém hữu ích.
- Có thể gây nhầm lẫn cho một số người dùng. Ví dụ: Trên một nền tảng phát nhạc trực tuyến, một bài hát được gắn thẻ cả "rock" và "điện tử" có thể khiến người dùng bối rối về thể loại của nó.
- Yêu cầu bảo trì để giữ cho thẻ nhất quán. Ví dụ: Trên một trang web việc làm, nếu một số tin tuyển dụng sử dụng thẻ "lập trình viên" (programmer) trong khi những tin khác sử dụng "nhà phát triển" (developer), sẽ trở nên khó tìm tất cả các công việc liên quan.
Khi nào nên sử dụng
- Đối với nội dung có nhiều danh mục. Ví dụ: Một trang web tin tức có thể gắn thẻ bài viết với "chính trị", "kinh tế", "quốc tế", cho phép một bài viết xuất hiện trong nhiều mục.
- Khi bạn cần tổ chức linh hoạt. Ví dụ: Một ứng dụng quản lý công việc cá nhân nơi người dùng có thể gắn thẻ nhiệm vụ là "công việc", "nhà", "khẩn cấp", "dài hạn" theo bất kỳ kết hợp nào.
- Đối với nội dung do người dùng tạo. Ví dụ: Một nền tảng mạng xã hội nơi người dùng có thể tạo và sử dụng thẻ hashtag của riêng mình để phân loại bài đăng.
Khi nào không nên sử dụng
- Đối với cấu trúc đơn giản, phân cấp. Ví dụ: Một trang web công ty nhỏ với các mục rõ ràng như "Giới thiệu", "Dịch vụ", "Liên hệ" không cần hệ thống thẻ.
- Khi bạn cần phân loại nghiêm ngặt. Ví dụ: Một danh mục thư viện nơi các cuốn sách phải nằm trong các danh mục cụ thể để sắp xếp trên kệ.
- Đối với lượng nội dung rất nhỏ. Ví dụ: Một blog cá nhân chỉ có 5-10 bài viết không cần hệ thống thẻ phức tạp.
Ví dụ với Ruby on Rails
Giả sử bạn đang tạo một blog về phim ảnh. Đây là cách bạn có thể thiết lập hệ thống thẻ:
Tạo các mô hình:
class Movie < ApplicationRecord
has_many :taggings
has_many :tags, through: :taggings
end
class Tag < ApplicationRecord
has_many :taggings
has_many :movies, through: :taggings
end
class Tagging < ApplicationRecord
belongs_to :movie
belongs_to :tag
end
Thêm thẻ vào một bộ phim:
movie = Movie.create(title: "The Avengers")
movie.tags.create(name: "Hành động")
movie.tags.create(name: "Siêu anh hùng")
Tìm phim theo thẻ:
action_movies = Tag.find_by(name: "Hành động").movies
Hệ thống đơn giản này cho phép bạn gắn thẻ phim và dễ dàng tìm phim với các thẻ cụ thể.
Chúng ta sẽ mở rộng ví dụ Ruby on Rails để xử lý việc chỉnh sửa phim và cập nhật các thẻ của chúng. Chúng ta sẽ tập trung vào việc thêm thẻ mới, liên kết các thẻ hiện có, và loại bỏ các thẻ mà người dùng không muốn nữa.
Trong mô hình Movie, thêm một phương thức để cập nhật thẻ:
class Movie < ApplicationRecord
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings
def update_tags(new_tag_names)
# Chuyển tên thẻ thành chữ thường để nhất quán
new_tag_names = new_tag_names.map(&:downcase).uniq
# Tìm các thẻ hiện có
existing_tags = Tag.where(name: new_tag_names)
# Tạo các thẻ mới chưa tồn tại
new_tags = new_tag_names - existing_tags.pluck(:name)
new_tags.each { |name| existing_tags << Tag.create(name: name) }
# Cập nhật các thẻ của phim
self.tags = existing_tags
# Loại bỏ các thẻ không sử dụng (tuỳ chọn)
Tag.where.not(id: Tag.joins(:taggings).distinct).destroy_all
end
end
Trong controller, sử dụng phương thức này khi cập nhật phim:
class MoviesController < ApplicationController
def update
@movie = Movie.find(params[:id])
if @movie.update(movie_params)
@movie.update_tags(params[:tags].split(',').map(&:strip))
redirect_to @movie, notice: 'Movie was successfully updated.'
else
render :edit
end
end
private
def movie_params
params.require(:movie).permit(:title, :description)
end
end
Trong view form của bạn, bạn có thể có một trường văn bản cho các thẻ:
<%= form_with(model: @movie, local: true) do |form| %>
<%= form.text_field :title %>
<%= form.text_area :description %>
<%= text_field_tag 'tags', @movie.tags.pluck(:name).join(', ') %>
<%= form.submit %>
<% end %>
