+1

Sử dụng Hash IDs cho URL với Ruby on Rails

Introduction

Khi phát triển ứng dụng web của bạn với Ruby on Rails, bạn thường gặp và sử dụng ID trong URL của bạn (/articles/1, articles/1/edit, ...). Thường đây là id auto-increment ở trong database. Để tạo thêm sự an toàn hơn, tránh việc dự đoán được từ phía users, mình nên sử dụng url format khác như sử dụng format text hoặc UUIDs, Hash IDs.... Hôm này mình xin giới thiệu một kỹ thuật là cách sử dụng Hash IDs cho URL.

USAGE

  • Ở đây mình sẽ sử dụng gem https://github.com/norman/friendly_id gem "friendly_id" giúp bạn tạo url với những format khác nhau như kiểu text (slug), hoặc custom format khác, ... Ở đây mình sẽ sử dụng gem này để customize url thành dạng Hash IDs.
# Gemfile
gem 'friendly_id', '~> 5.1.0'
bundle install
  • Thêm column hash_id vào model:
class AddHashIdToTable < ActiveRecord::Migration[5.0]
  def change
    add_column :hash_id, :table_name, :string, index: true
  end
end
  • Tạo model concern: module này dùng để generate ra Hash IDs cho model trước khi lưu vào db. Mỗi hash_id trong db phải khác nhau, vậy trước khi lưu vào db, phải kiểm tra và đảm bảo là hash_id đó là chưa có.
# app/models/concerns/friendlyable.rb

module Friendlyable
  extend ActiveSupport::Concern
  included do 
    extend ::FriendlyId
    before_create :set_hash_id
    friendly_id :hash_id
  end
  
  def set_hash_id
    hash_id = nil
    loop do
      hash_id = SecureRandom.urlsafe_base64(9).gsub(/-|_/,('a'..'z').to_a[rand(26)])
      break unless self.class.name.constantize.where(:hash_id => hash_id).exists?
    end
    self.hash_id = hash_id
  end
end
  • Bây giờ mình đã có module để generate ra hash_id rồi, tiếp theo mình phải include module đó vào trong những model mình cần tạo hash_id.
class User < ApplicationRecord
  include Friendlyable
   ...
end
  • Đến đây bạn đã có hash_id cho urls rồi, bây giờ url của bạn sẽ thành dạng như sau: http://localhost:3000/users/90upoijsz Tiếp theo để tìm records, mình sẽ sử dụng như sau:
User.friendly.find(params[:id])

Thay vì tìm theo id, bây giờ sẽ tìm theo hash_id.

Bạn có thể tham khảo chi tiết hơn: https://github.com/norman/friendly_id https://hackernoon.com/how-to-use-hash-ids-in-your-url-in-ruby-on-rails-5-e8b7cdd31733 http://norman.github.io/friendly_id/


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.