> For the complete documentation index, see [llms.txt](https://aaron-mota.gitbook.io/aarons-style-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://aaron-mota.gitbook.io/aarons-style-guide/backend/rails/file-setups/routes-routes.rb.md).

# Routes (routes.rb)

### Overview

* **Setup**
  * [**Verbose (with notes & example)**](#setup-with-notes-and-examples)
  * [**Concise**](#setup-concise)

### **Related**

* [**Controllers Setup**](broken://pages/X8xSPUstyHxQCGWlZJ0y)

***

## Setup

### Verbose -- with notes, explanations, examples

*(best viewed copy/pasted into a code editor)*

```ruby
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)*

```ruby
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
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://aaron-mota.gitbook.io/aarons-style-guide/backend/rails/file-setups/routes-routes.rb.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
