Something about Rails routes

Tính năng resources trong routes là rất hữu ích, nhưng khi bắt đầu với RoR, một số tính năng được xây dựng trên nó có thể khiến bạn khó mà tự giải thích được. Bài viết sẽ giúp bạn hiểu và có thể sử dụng routes một cách hiệu quả! 😉

basic information about resources

Resources giúp bạn viết một cách ngắn gọn hơn nhưng mô tả một cách đầy đủ các route cơ bản trong ứng dụng của bạn. Khi bạn xác định một resources route, nó sẽ tạo các route cho tất cả các action CRUD cho bạn theo quy ước rails (rails conventions).

resource and resources

Sự khác biệt rõ ràng đầu tiên giữa resourcesresources, có nghĩa là resource là số nhiều (plural) hoặc số ít (singular).

Routes được tạo ra với resources: gồm 7 routes

Prefix Verb URI Pattern Controller#action
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/(.:format) users#edit
user GET /users/:id/(.:format) users#show
PUT/ PATCH /users/:id/(.:format) users#update
DELETE /users/:id/(.:format) users#destroy

Trong khi đó, Routes được tạo ra với resource là :

Prefix Verb URI Pattern Controller#action
new_users GET /users/new(.:format) users#new
edit_users GET /users/(.:format) users#edit
users GET /users/(.:format) users#show
PUT/ PATCH /users/(.:format) users#update
DELETE /users/(.:format) users#destroy
POST /users(.:format) users#create

Như bạn thấy không có ID trong các route pattens khi sử dụng resourceresource không tạo ra bất kỳ route nào mà được xử lý với action index.

Vậy khi nào thì sử dụng resource ? 🤔🤔

Ez! Đôi khi, bạn tra cứu mà không cần tham chiếu đến ID. Ví dụ: bạn muốn /profile luôn hiển thị profile của người dùng hiện đang đăng nhập. Trong trường hợp này, bạn có thể sử dụng singular resource để ánh xạ /profile (thay vì /profile/: id) với action show. Hoặc ví dụ khác, một user thường thuộc 1 organization duy nhất, do đó để xem profile của organization đó, ta có thể có 2 routes:

  1. /organizations/:id
  2. /organization #simply

Ở đây, việc triển khai route theo cách thứ 2 có ý nghĩa hơn, đúng không nhỉ? Bạn lấy đối tượng organization từ association với user:

#in organizations#show 
@organization = current_user.organization

only and except

Nếu bạn muốn chỉ có các route cụ thể của resource(s) route , bạn có thể thêm các exceptions trong “only” hoặc “except”

Rails.application.routes.draw do
  resources :users, only: [:index]
  resources :customers, except: [:create, :show, :update, :destroy]
end

Generated Routes sẽ là :

# Prefix         Verb          URI Pattern                     Controller#Action
# users          GET           /users(.:format)                users#index
# customers      GET           /customers(.:format)            customers#index
# new_customer   GET           /customers/new(.:format)        customers#new
# edit_customer  GET           /customers/:id/edit(.:format)   customers#edit

collection route?

Bằng cách sử dụng collection, bạn có thể thêm các routes bổ sung vào controller. Bạn chỉ cần tạo một collection route mới và xác định một phương thức có cùng tên với method trong controller. như bạn thấy cả hai cách tạo COLLECTION đều hoạt động:

Rails.application.routes.draw do
  resources :users do 
    collection do
      get :some_collection
    end
    get :another_collection, collection: true
  end
end

# Generated Routes
# Prefix                     Verb      URI Pattern                            Controller#Action
# some_collection_users      GET       /users/some_collection(.:format)       users#some_collection
# another_collection_users   GET       /users/another_collection(.:format)    users#another_collection

member in route?

member giống như collection nhưng chúng có một id trong route được tạo, có nghĩa là route này thuộc về một thành viên của resource

Và cũng có hai cách tạo MEMBER:

Rails.application.routes.draw do
  resources :users do
    member do
      get :some_member
    end
    get :another_member, on: :member
  end
end

# Generated Routes
# Prefix                   Verb      URI Pattern                            Controller#Action
# some_member_user         GET       /users/:id/some_member(.:format)       users#some_member
# another_member_user      GET       /users/:id/another_member(.:format)    users#another_member

Alright! Bằng cách sử dụng các phương pháp này, code của bạn sẽ clean và dễ đọc hơn.
Hẹn gặp lại ở post tiếp theo ! 😆😆

Reference

  1. Maybe you don’t know these about Rails routes!
  2. Routing in Rails
  3. Routing

All Rights Reserved