Giới thiệu
Chắc hẳn khi đọc tiêu đề thì bạn đã đoán được URL shortener là gì rồi, nó đơn giản chỉ là công cụ rút ngắn URL nhìn gọn hơn, giúp cho việc chia sẽ dễ dàng hơn khi hiện nay nhiều website, app có message, content bị giới hạn ký tự. Ở bài viết này mình cũng sẽ thử build một ứng dụng tương tự để rút gọn URL với Rails, nhìn chung thì nó sẽ hoạt động như sau:
- Input nhập một URL và output là một URL đã rút ngắn.
- Có thể sử dụng URL mới đó đó để chia sẻ.
- Khi click vào URL mới, sẽ chuyển hướng đến URL gốc.
- Bạn có thể xem số liệu thống kê về số lần đã click vào URL mới này.
Chuẩn bị
Đầu tiên new project với Rails và config DB.
rails new demo_url_shortener -d mysql
Tiếp theo tạo model, ở đây tạo với scaffold cho nhanh, nhớ bổ sung cột t.integer :clicked, default: 0 và add_index :short_links, :shorted_code, unique: true vì chúng ta sẽ dùng shorted_code này search nhiều.
rails g scaffold short_link origin_url:string shorted_code:string clicked:integer
class CreateShortLinks < ActiveRecord::Migration[5.2]
def change
create_table :short_links do |t|
t.string :origin_url
t.string :shorted_code
t.integer :clicked, default: 0
t.timestamps
end
add_index :short_links, :shorted_code, unique: true
end
end
rails db:migrate
Tiếp theo sửa lại file routes.rb và view một tí: app/views/short_links/_form.html.erb
Rails.application.routes.draw do
root to: "short_links#index"
resources :short_links
get "/:shorted_code", to: "short_links#show", as: :short
end
<%= form_with(model: short_link, local: true) do |form| %>
<div class="field">
<%= form.label :origin_url %>
<%= form.text_field :origin_url %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
Code thôi nào
Ở file model app/models/short_link.rb bổ sung thêm validates và viết function để generate shorted_code.
Ở đây mình dùng urlsafe_base64 (SecureRandom) để generate, cái này không bắt buộc đâu bạn có thể dùng bất kỳ kiểu nào cũng được.
validates :shorted_code, uniqueness: true
before_save :generate_shorted_code
private
def generate_shorted_code
self.shorted_code = SecureRandom.urlsafe_base64(10)
generate_shorted_code if duplicate?
end
def duplicate?
ShortLink.where(shorted_code: shorted_code).exists?
end
Để đề phòng trường hợp generate shorted_code bị trùng với cái đã có trong DB, ta viết thêm một function duplicate? để check thêm nhằm bảo đảm chỉ cần nhập URL thì chắc chắn chỉ có một shorted_code duy nhất, trong trường hợp bị trùng sẽ
generate ra một shorted_code mới chứ không trả về lỗi.
Gọi function generate_shorted_code bằng callbacks before_save :generate_shorted_code
Tiếp theo sửa code ở file app/controllers/short_links_controller.rb
class ShortLinksController < ApplicationController
def index
@short_links = ShortLink.all
end
def new
@short_link = ShortLink.new
end
def create
@short_link = ShortLink.create(short_link_params)
redirect_to root_path
end
private
def short_link_params
params.require(:short_link).permit(:origin_url)
end
end
Sau khi hoàn tất các bước trên ta đã có thể tạo một short_link như thế này rồi.
Bước tiếp theo ta dùng shorted_code mới này để chuyển hướng đến origin_url.
Ở controller
app/controllers/short_links_controller.rb, với phương thức update_columns này sẽ không gọi lại callback nữa nên bạn yên tâm nó sẽ không generate ra shorted_code mới đâu.
before_action :load_short_link, only: :show
def show
@short_link.update_columns(clicked: (@short_link.clicked + 1))
redirect_to URI(@short_link.origin_url).to_s
end
private
def load_short_link
@short_link = ShortLink.find_by shorted_code: params[:shorted_code]
end
Ok giờ thì chúng ta có thể đã có thể click vào http://localhost:3000/pUJg_ca8bxoXEg thì sẽ đến trang gốc https://www.zauberware.com/en/articles/2019/create-a-url-shortener-with-ruby-on-rails như ta mong muốn.
Kiểm tra lại khi quay lại trang index thì column clicked đã tăng lên 1 rồi.
Kết
Trên là bài viết cơ bản để có thể xây dựng chức năng URL shortener với Rails, bạn có thể tham khảo thêm ở những link bên dưới
https://www.zauberware.com/en/articles/2019/create-a-url-shortener-with-ruby-on-rails
https://medium.com/@sparkboldstudio/building-a-url-shortener-rails-app-96db60d3bf9d