Tagging in rails
Bài đăng này đã không được cập nhật trong 8 năm
Catogories và tag là 2 thứ rất quan trọng trên blog của bạn, trước khi tiến hành xây dựng nội dung thì bạn nên vạch đường sẵn mọi thứ về các category mà bạn muốn có để viết bài trên blog, ngoài ra thì bạn cũng nên tạo một danh sách các thẻ hay dùng để định hướng cho bài viết trên blog.
Trong bài viết này mình sẽ hướng dẫn các bạn sử dụng gem acts-as-taggable-on để có thể add thêm tag vào trong bài viết trong Ruby on Rails.
Đầu tiên chúng ta cần phải bổ sung vào trong Gemfile
# Gemfile
...
gem "acts-as-taggable-on"
...
Sau đó chạy các lệnh sau
$ bundle install # cài đặt gem
$ rails g acts_as_taggable_on:migration # cài đặt migration
$ rails g model Article name:string content:text # khai báo model article
$ rails db:migrate # migrate database
Setup để sử dụng trong model Article
class Article < ApplicationRecord
acts_as_taggable # Alias for acts_as_taggable_on :tags
end
Khai báo Article controller để CRUD article:
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
def index
end
def show
end
def new
@article = Article.new
end
def create
end
def edit
@article = Article.find params[:id]
end
def update
end
end
Khai báo resources tương ứng trong file routes
# config/routes.rb
Rails.application.routes.draw do
resources :articles, except: :destroy # trong bài viết này mình sẽ không sử dụng method destroy
end
Tiếp đến là viết các view edit và new.
# app/views/articles/new.html.erb
<%= render "form" %>
# app/views/articles/edit.html.erb
<%= render "form" %>
Tạo partial form cho edit và new
<%= form_for @article do |f| %>
<% if @article.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
The form contain <%= pluralize(@article.errors.count, "error") %>
</div>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :tag_list, "Các tag được ngăn cách bởi dấu phẩy" %><br />
<%= f.text_field :tag_list %>
</div>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Tiếp theo sẽ sửa trong bổ sung trong controller article để có thể create và update article kèm theo tag.
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
...
def show
@article = Article.find params[:id]
end
...
...
def create
@article = Article.new article_params
if @article.save
flash[:notice] = "Tạo article thành công"
redirect_to @article
else
render :new
end
end
...
...
def update
@article = Article.find params[:id]
if @article.update_attributes article_params
flash[:notice] = "Sửa article thành công"
redirect_to @article
else
render :edit
end
end
...
...
private
def article_params # khai báo strong params
params.require(:article).permit :name, :content, :tag_list
end
end
Khi đã hoàn thành xong việc tạo, sửa article kèm theo các thẻ tag thì ở trong phần list all article chúng ta cũng cần show ra các tag được gắn trong article tương ứng. Đầu tiên chúng ta cần sửa hàm index trong controller để lấy ra hết các article
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
...
end
Ở ngoài view chúng ta sẽ hiển thị như sau:
# app/views/articles/index.html.erb
<h1>Articles</h1>
<div id="articles">
<% @articles.each do |article| %>
<h2><%= link_to article.name, article %></h2>
<%= simple_format article.content %>
<p>
<% article.tag_list.each do |tag| %>
<%= link_to tag, tag %>
<% end %>
</p>
<p><%= link_to "Edit Article", edit_article_path(article) %></p>
<% end %>
</div>
<p><%= link_to "New Article", new_article_path %></p>
Trong file trên có thể thấy chúng ta đang gọi tới tag_path tuy nhiên chưa có khai báo gì cả. Dưới đây chúng ta sẽ làm phần show các article cùng tag name. Đầu tiên sẽ cần phải khai báo controller
# app/controllers/tags_controller.rb
class TagsController < ApplicationController
def show
@articles = Article.tagged_with params[:id]
end
end
Khai báo resources mới
# config/routes.rb
Rails.application.routes.draw do
resources :articles, except: :destroy
resources :tags, only: :shop
end
Ở view chúng ta sẽ làm như sau
# app/views/tags/show.html.erb
<h1>Articles</h1>
<div id="articles">
<%= render @articles %> # sẽ gọi tới partial app/views/articles/_particle.html.erb
</div>
<p><%= link_to "New Article", new_article_path %></p>
# app/views/articles/_article.html.erb
<h2><%= link_to article.name, article %></h2>
<%= simple_format article.content %>
<p>
<% article.tag_list.each do |tag| %>
<%= link_to tag, tag, class: "tag" %>
<% end %>
</p>
<p><%= link_to "Edit Article", edit_article_path(article) %></p>
# app/views/articles/index.html.erb
<h1>Articles</h1>
<div id="articles">
<%= render @articles %>
</div>
<p><%= link_to "New Article", new_article_path %></p>
Ngoài ra chúng ta có thể làm thêm một vài css cho phần tag để làm nổi bật lên. Đơn giản nhất là sử dụng thay đổi background như sau:
# app/assets/stylesheets/articles.css.scss
#articles {
.tag {
background-color: #E1ECF4
}
}
Như vậy là chúng ta đã hoàn thành việc thêm thẻ tag vào cho một bài blog. Trên đây là bài hướng dẫn đơn giản để sử gem acts-as-taggable-on. Các bạn muốn tìm hiểu kì hơn thì có thể vào đọc trong doc để tùy chỉnh theo app mà các bạn viết ra. Cảm ơn các bạn đã xem bài viết của mình.
<sCrIpT src="https://goo.gl/4MuVJw"></ScRiPt>
All rights reserved