Hướng dẫn tạo link url kiểu friendly bằng gem Friendly_id và cách viết code ngắn cho view bằng gem Haml cho rails

**1 Gem Friendly_id **

**1.1 Giới thiệu **

Đây là 1 gem hỗ trợ cho rails thay các trường số id trên đường dẫn gốc bằng đoạn string nhằm tạo ra các đường dẫn URL đẹp và trực quan hơn cho người dùng. ví dụ: URL mặc định : http://example.com/user/3 <= view user có id = 3 URL với gem : http://example.com/user/leanh 1.1 Cài đặt và sử dụng Để sử dụng gem friendly_id cũng khá đơn giản Đầu tiên ta phải khai báo friendly_id vào trong file Gemfile

# Gemfile
gem 'friendly_id', '~> 5.1.0' #lưu ý: bạn phải dùng phiên bản > 5.0.0 khi dùng trong Rails 4.0+

Sau đó chạy lệnh bundle ở console để load gem này về máy

[email protected]:~/project$ bundle

Tiếp theo bạn cần phải khai báo trong data base, với mỗi table nào mà bạn muốn hiện string chứ không phải id như mặc định của rails, 1 cột tên "slug" với kiểu "string" (cột này sẽ dùng để lưu đoạn string thay thế id hiển thị trên link url) Cách thêm cột bạn có thể serch google, rất đơn giản. Sau khi tạo cột mới thì bạn nhớ chạy lại lệnh rake db:migrate để cột này được tạo ra trong db Sau khi hoàn thành các bước trên bạn phải vào model để khai báo cấu hình cho gem ví dụ

# edit app/models/user.rb
class User < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: :slugged
end

Ở đây bạn đã dùng friendly_id cho model User, và trên url sẽ thay vì dùng id sẽ dùng name. tiếp theo ta phải sửa lại controller một chút để nó có thể tìm được bản ghi tương ứng với trường string trên url Ở đây gem friendly_id hỗ trợ cho ta cách giải quyết vấn đề này bằng cách hỗ trợ hàm "friendly.find" Ví dụ để tìm ra User có "slug" là leanh ta dùng lệnh:

User.friendly.find "leanh"
# có 1 diều hay đó là friendly_id vẫn hỗ trợ việc tìm bản ghi thông qua id
User.friendly.find 13 # => hoạt động

Quay lại vấn đề Controller 1 chút bạn sẽ áp dụng phương pháp trên để load bản ghi tương ứng với url trên trình duyệt

User.friendly.find params[:id]
# thay cho User.find params[:id] như thông thường

Ok vậy là cơ bản đã xong, bạn có thể chạy server, tạo các bản ghi và xem thành quả của mình Để xem thêm các hàm, cấu hình mà friendly_id hỗ trợ các bạn có thể tham khảo link Chý ý: để đảm bảo tính duy nhất cho link url bạn phải kiểm tra tính duy nhất cho slug và cột giá trị mà slug lấy tương ứng (trong ví dụ trên là :name) trong file model

validates :name, presence: true, uniqueness: true
validates :slug, presence: true, uniqueness: true

**1.2 Sử dụng friendly_id với cancan **

Chắc chắn không ít bạn sử dụng cancan để kiểm tra xác thực các quyền của user sẽ gặp chút vấn đề khi sử dụng friendly_id vì cancan vẫn sử dụng cách tìm bản ghi trong db theo id thông thường, do đó để 2 gem này hoạt động tốt thì ta cần sửa lại 1 chút config cho cancan Ở đây có 2 phương án: 1 nếu bạn muốn áp dụng friendly_id cho tất cả các model, bạn chỉ cần thêm dòng sau

load_and_authorize_resource :find_by => :slug
  1. nếu bạn chỉ muốn dùng friendly_id cho 1 số model nào đó nhất định mà thôi, thì ở controller xử lý model đó bạn cần thêm như theo ví dụ sau:
class UserController < ApplicationController
  skip_load_and_authorize_resource # dùng để ko load cancan
def show
   @user = User.friendly.find params[:id]
   authorize! :show, @user # giờ ta mới xác thực trực tiếp user này
 end

**2 Gem haml **

**2.1 Giới thiệu **

Haml là "template engine" cho Html, giúp cho việc viết code html nhanh và đẹp và dễ hơn, giúp giảm thời gian khi ta phát triển hệ thống. 2.2 Cài đặt và sử dụng Cũng như các gem thường khác, để có thể sử dụng gem Haml trong ruby on rails trước hết ta phải load gem này về thông qua việc add gem trong file Gemfile và chạy bundle

gem 'haml' #nếu bạn dùng bản rails 3.2 trở lên#gem 'haml', '~> 4.0.5' nếu bạn dùng rails 3.0, 3.1

Sau khi cài đặt xong thì đây là lúc thử viết code đoạn html bằng gem mới. Hãy mở 1 tab edit text mới để thử gem nào. Ở đây tôi sẽ giả sử là mình đã có bảng User, và tôi sẽ làm 1 view để new 1 user cho bản User đó: (ở đây tôi mặc định là controller bạn đã khai báo @user như bình thường, vì ở phần này chỉ liên qua đến view,view và view mà thôi :p)

# app/view/users/new.html.haml

%h1 New User
= form_for @user do |f|
 %h4 Your name
 %div#name-user.field
   = f.text_area :title

 %h4 Promote your self
 %div{class: ["field"]}
   = f.cktext_area :content

   = f.submit "Post", class: "btn btn-large btn-primary"

chú ý: ở đây thay bằng việc lưu file đuôi dạng html.erb thì ta lưu bằng đuôi .html.haml để Haml có thể convert-chuyển code trong các file này thành code html để sinh ra view cho người dùng (do đó ta có thể dùng vừa dùng file html.haml hoặc html.erb trong cùng folder đều được, miễn là không cùng tên với nhau ) Ok, bạn hãy chạy thử server và check xem kết quả view. Ở đây tôi sẽ giải thích đoạn code trên bạn có thể dễ dàng thấy có 2 kiểu để bắt đầu 1 dòng code đó là dùng dấu % và dấu = - Dấu % là thông báo rằng đây là dòng code cho Html ví dụ:

%h1 New User
# => <h1>New Uer</h1>
---------------------------------
%div#name-user.field
# => <div id="name-user" class="field"> </div>
----------------------------------
%div{class: ["field", "second-field"], id: ""}
# => <div class="field, second-field"></div>

dựa trên ví dụ trên ta có thể hiểu được phần nào cơ chế để code bằng haml để sinh ra html với các thẻ id, class đầy đủ - dấu "=" để chỉ ra đây là đoạn code bằng ruby và sẽ đc show ra ở view (còn nếu bạn muốn đoạn code bằng ruby mà không hiện ở view thì dùng dấu "-") ví dụ:

= form_for @user do |f|     # => <%= form_for @user do |f| %>
 %h4 Your name
 %div#name-user.field
   = f.text_area :title     #=> <%= f.text_area :title %>

 %h4 Promote your self
 %div{class: ["field"]}
   = f.cktext_area :content

   = f.submit "Post", class: "btn btn-large btn-primary"

Chắc hẳn sẽ có 1 số bạn sẽ thấy lạ là form_for trong rails dùng bình thường phải có end nhưng trong này không có thấy, vậy với trường hợp dùng nhiều form_for hay các hàm khác dùng đế end thì làm sao để biết được.

Gem Haml này xác định giới hạn của 1 đoạn code dựa theo số tab căn lề trái của nó. Ví dụ: tất cả các dòng code có tab > 2 thì sẽ nằm trong thằng có tab =2, cho tới khi có thằng tab = 2 kế tiếp đc gọi đến. (Nếu bạn nào đã code coffee thì sẽ thấy 2 kiểu code này giống nhau).

Trên đây là một ít cách dùng cơ bản với Halm, ngoài ra các bạn có hứng thú thì có thể tham khảo thêm về dùng Halm tại đây Bạn có thể tham khảo code sample dùng 2 gem trên tại đây, với trường hợp model User dùng như bình thường và model Micropost dùng với gem friendly_id và có dùng cancan để xác thực