Routes (routes.rb)
routes.rb
Overview
Related
Controllers Setup
Setup
Verbose -- with notes, explanations, examples
(best viewed copy/pasted into a code editor)
namespace :api do
namespace :v2 do
#####################################################################
#####################################################################
# NOTES
#####################################################################
#####################################################################
#####################################
# ROUTING STYLE GUIDE / CONVENTIONS:
#####################################
# 1. Path Naming:
# - Use hyphenated paths for multi-word resources (e.g., /team-members).
# - Singular or plural form should reflect the resource it refers to (e.g., resources :equipments uses path: '/equipment').
# 2. CRUD Actions:
# - For APIs, typically, only the following 5 Rails default controller actions are utilized: :index, :show, :create, :update, :destroy.
# - The other 2 ('new' and 'edit') are not needed for APIs as they don't render views. (7 default controller actions: https://guides.rubyonrails.org/routing.html#crud-verbs-and-actions)
# 3. Custom Actions:
# - "Collection" actions apply to the resource as a whole (e.g., POST '.../users/invite_users'). (collection: https://guides.rubyonrails.org/routing.html#adding-collection-routes)
# - "Member" actions apply to specific instances of the resource (e.g., PUT '.../users/1/accept_terms'). (member: https://guides.rubyonrails.org/routing.html#adding-member-routes)
# 4. Nested Routes:
# - Use for representing resource relationships.
# - For one-to-one relationships, use 'resource' (singular).
# - For one-to-many or many-to-one relationships, use 'resources' (plural).
# 5. Scopes:
# - Utilized for representing many-to-many relationships or to organize custom functionality under specific modules.
# 6. Organizing Nested Features:
# - Within a resource block, the following order is recommended for clarity:
# (1) Relationships: This includes scopes (e.g. many-to-many relationships), nested resources (e.g. one-to-one, one-to-many), and indicates how the primary resource relates to others.
# (2) Collection/Model actions: Custom operations at the collection or individual resource level.
# (3) Non-collection/non-model actions: Specialized actions that don't directly fit into collection or model categorization (see more below).
# 7. Non-collection/non-model Actions:
# - These actions don't operate on the primary resource or its collection directly.
# - Examples include utility or helper actions, aggregated data, reports, or operations involving multiple types of resources.
# - More about non-collection/non-model actions: https://guides.rubyonrails.org/routing.html#adding-more-restful-actions
#####################################
# SCOPE FOR ADDITIONAL CUSTOMIZATIONS:
#####################################
# As the project evolves, there might be a need for more customization. This section serves as a placeholder for
# "constraints" on routes, advanced query parameters, or other custom requirements. This will guide future development.
# 1. Constraints:
# - Constraints limit the matches a route can make.
# - For example: constraints might be used to specify that a parameter must match a certain pattern or set of values.
# - More on constraints: https://guides.rubyonrails.org/routing.html#segment-constraints
# Example:
# constraints(id: /\d{1,5}/) do
# resources :posts
# end
# (e.g. api.get('.../posts/1') -- matches, but api.get('.../posts/abc') -- does not match
# 2. Advanced Query Parameters:
# - Some routes might require more advanced filtering or sorting mechanisms.
# - Consider using gems like 'ransack' for this purpose or handling them manually in the controller.
# Example:
# get 'search', to: 'controller#search'
# 3. Other Customizations:
# - Place other route customizations or special requirements here.
#####################################################################
#####################################################################
# EXAMPLES ROUTES.RB SETUP
#####################################################################
#####################################################################
#####################################
# RESOURCE-RELATED ROUTES (top-level routes)
#####################################
# Note:
# - resource = a top-level model (e.g. 'contacts', 'equipments', 'team_members', etc.) (https://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default)
# ROUTES WITH ONLY BASIC CRUD ACTIONS
##################################
resources :contacts, only: [:index, :show, :create, :update, :destroy] # default path is '/contacts' (only need to specify if you want to change it from the default -- e.g. hyphenated paths)
resources :equipments, path: '/equipment', only: [:index, :show, :create, :update, :destroy]
resources :team_members, path: '/team-members', only: [:index, :show, :create, :update, :destroy]
resources :production_goals, path: '/production-goals', only: [:index, :show, :create, :update, :destroy]
resources :quality_goals, path: '/quality-goals', only: [:index, :show, :create, :update, :destroy]
# ...add other resources (top-level) here
# ROUTES WITH CUSTOM "CRUD-LIKE" ACTIONS
##################################
resources :users, only: [:index, :show, :create, :update, :destroy] do
# COLLECTION/MEMBER-RELATED ACTIONS:
collection do
post :invite_users # (e.g. api.post('.../users/invite_users') -- invite many users)
get :index_all
post :update_page_seen
# ...add other collection methods here
end
member do
put :accept_terms # (e.g. api.put('.../users/1/accept_terms') -- accept terms for single user)
get :my_info
# ...add other member methods here
end
# ...add other non-collection/non-member methods here
end
#####################################
# RELATIONSHIP HANDLING (nested/non-top-level routes, etc.)
#####################################
# Note:
# - A single top-level resource can have all 4 types of relationships (one-to-one, one-to-many, many-to-one, many-to-many), but they are separated out here for clarity and organization.
# ONE-TO-ONE (one profile has one user, and that user only has that profile)
##################################
resources :users, only: [:index, :show, :create, :update, :destroy] do
# RESOURCE-RELATED ROUTES (NESTED):
resource :profile, only: [:show, :create, :update, :destroy] # notice 'resource' (singular) is used for a one-to-one association.
# ...add other resources (nested) / relationships here
# ...add other collection/member methods here
# ...add other non-collection/non-member methods here
end
# ONE-TO-MANY (one author has many books, one book has one author)
##################################
resources :authors, only: [:index, :show, :create, :update, :destroy] do
# RESOURCE-RELATED ROUTES (NESTED):
resources :books, only: [:index, :show, :create, :update, :destroy]
# ...add other resources (nested) / relationships here
# ...add other collection/member methods here
# ...add other non-collection/non-member methods here
end
# MANY-TO-ONE
##################################
# (":books" in the above example -- the Many-to-One resource is always nested within the One-to-Many resource)
# MANY-TO-MANY:
##################################
resources :projects, only: [:index, :show, :create, :update, :destroy] do
# RELATIONSHIP ROUTE: contacts
scope module: 'project_contacts' do
post "/equipment/:contact_id/link", to: "linking#create" # (e.g. api.post('.../projects/1/equipment/1/link') -- link a contact to a project)
delete "/equipment/:contact_id/unlink", to: "linking#destroy" # (e.g. api.delete('.../projects/1/equipment/1/unlink') -- unlink a contact from a project)
end
# RELATIONSHIP ROUTE: team_members
scope module: 'project_team_members' do
post "/team-member/:team_member_id/link", to: "linking#create" # (e.g. api.post('.../projects/1/team-member/1/link') -- link a team_member to a project)
delete "/team-member/:team_member_id/unlink", to: "linking#destroy" # (e.g. api.delete('.../projects/1/team-member/1/unlink') -- unlink a team_member from a project)
end
# ...add other resources (nested) / relationships here
# ...add other collection/model methods here
# ...add other non-collection/non-model methods here
end
end
end
Concise -- removed notes and explanations
(best viewed copy/pasted into a code editor)
namespace :api do
namespace :v2 do
# ROUTES WITH BASIC CRUD ACTIONS
resources :contacts, only: [:index, :show, :create, :update, :destroy]
resources :equipments, path: '/equipment', only: [:index, :show, :create, :update, :destroy]
resources :team_members, path: '/team-members', only: [:index, :show, :create, :update, :destroy]
resources :production_goals, path: '/production-goals', only: [:index, :show, :create, :update, :destroy]
resources :quality_goals, path: '/quality-goals', only: [:index, :show, :create, :update, :destroy]
# ROUTES WITH CUSTOM "CRUD-LIKE" ACTIONS
resources :users, only: [:index, :show, :create, :update, :destroy] do
collection do
post :invite_users
get :index_all
post :update_page_seen
end
member do
put :accept_terms
get :my_info
end
end
# ROUTES WITH RELATIONSHIPS
# ONE-TO-ONE
resources :users, only: [:index, :show, :create, :update, :destroy] do
resource :profile, only: [:show, :create, :update, :destroy]
end
# ONE-TO-MANY (and MANY-TO-ONE)
resources :authors, only: [:index, :show, :create, :update, :destroy] do
resources :books, only: [:index, :show, :create, :update, :destroy]
end
# MANY-TO-MANY
resources :projects, only: [:index, :show, :create, :update, :destroy] do
scope module: 'project_contacts' do
post "/equipment/:contact_id/link", to: "linking#create"
delete "/equipment/:contact_id/unlink", to: "linking#destroy"
end
scope module: 'project_team_members' do
post "/team-member/:team_member_id/link", to: "linking#create"
delete "/team-member/:team_member_id/unlink", to: "linking#destroy"
end
end
end
end
Last updated