12/08/2018, 13:44

Tagging in rails

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

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.

0