12/08/2018, 17:59

Paper Trail Gem

Papel Trail là gem dùng để theo dõi các thay đổi đối với model của bạn, kiểm tra hoặc versioning. Cài đặt Papel Trail: Thêm gem Papel Trail vào Gemfile: gem "paper_trail" Chạy lệnh: bundle install Thêm table versions bundle exec rails generate paper_trail:install Sau khi chạy lệnh ...

Papel Trail là gem dùng để theo dõi các thay đổi đối với model của bạn, kiểm tra hoặc versioning.

  1. Cài đặt Papel Trail:

Thêm gem Papel Trail vào Gemfile:

gem "paper_trail"

Chạy lệnh: bundle install

Thêm table versions

bundle exec rails generate paper_trail:install

Sau khi chạy lệnh trên, sẽ sinh ra 1 file migration như sau:

class CreateVersions < ActiveRecord::Migration[5.0]

  
  TEXT_BYTES = 1_073_741_823

  def change
    create_table :versions, { options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci" } do |t|
      t.string   :item_type, {:null=>false, :limit=>191}
      t.integer  :item_id,   null: false
      t.string   :event,     null: false
      t.string   :whodunnit
      t.text     :object, limit: TEXT_BYTES

      t.datetime :created_at
    end
    add_index :versions, %i(item_type item_id)
  end
end

Sau đó tiếp tục chạy lệnh:

bundle exec rake db:migrate

Như vậy, quá trình cài đặt gem paper_trail đã xong.

  1. Sử dụng:

Thêm has_paper_trail vào các model để tracking sự thay đổi.

class Car < ApplicationRecord
  extend FriendlyId
  friendly_id :name, use: :slugged

  has_paper_trail

  belongs_to :category
end

Thêm before_action :set_paper_trail_whodunnit vào ApplicationController để tracking ai đã change version model. Xem lịch sử thay đổi:

car = Car.last

car.name # xxx

 car.versions #<ActiveRecord::Associations::CollectionProxy []>
 
 car.update_attributes name: "New name"

Kiểm tra lại lịch sử thay đổi:

car.versions

#<ActiveRecord::Associations::CollectionProxy [#<PaperTrail::Version id: 4, item_type: "Car", item_id: 22, event: "update", whodunnit: nil, object: "--- id: 22 name: xxx cost: 1 version: awidth: hei...", created_at: "2018-06-06 06:23:27">]>

Lấy ra dữ liệu trước khi thay đổi: car.versions.last.reify

Xem sự kiện thay đổi record:

car.versions.last.event #"update"

Revert model:

Như ở ví dụ trên, chúng ta đã thay đổi tên của cả từ "xxx" thành "New name", vậy làm sao để revert nó lại như ban đầu? Lấy lại thay đổi ở version trước:

car.paper_trail.previous_version

Và thực hiện:

previous.saveđể revert.

0