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.
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 %>