Skip to content

Instantly share code, notes, and snippets.

@justalever
Created June 7, 2021 18:30
Show Gist options
  • Save justalever/05772795637709014ef340fbda923099 to your computer and use it in GitHub Desktop.
Save justalever/05772795637709014ef340fbda923099 to your computer and use it in GitHub Desktop.
Ruby on Rails routing
# This is for reference via the blog post/view at https://web-crunch.com/posts/ruby-on-rails-routing
require 'sidekiq/web'
Rails.application.routes.draw do
authenticate :user, lambda { |u| u.admin? } do # ensures authenticated users who are admins can only access anything within this block
mount Sidekiq::Web => '/sidekiq' # built into the sidekiq gem
end
devise_for :users # built into the Devise gem
# Why routing anyway?
# The Rails router recognizes URLs and dispatches them to a controller's action, or to a Rack application. It can also generate paths and URLs, avoiding the need to hardcode strings in your views.
# ===== ROOT PATH (the default page your app resolves to. This can be anything.)
# pass the controller name and action explicitly. controller_name#action
root to: 'home#index'
# ======= RESOURCES (Fully RESTful routing in a one-liner) ======
resources :posts
# can also be define in multiples (though less common)
resources :posts, :categories, :tags
# This gives you GET, POST, PATCH, DELETE restful routing OR in Rails terms: index, show, new, edit, create, update, and destroy actions on controllers (posts_controller.rb)
# GET /posts - posts#index - display a list of all posts
# GET /posts/new - posts#new - return an HTML form for creating a new posts
# POST /posts - posts#create - create a new posts
# GET /posts/:id - posts#show - display a specific posts
# GET /posts/:id/edit - posts#edit - return an HTML form for editing a posts
# PATCH/PUT /posts/:id - posts#update - update a specific posts
# DELETE /posts/:id - posts#destroy - delete a specific posts
# Examples:
# Putting this routing to use to use in views and helpers
# posts_path returns /posts
# new_post_path returns /posts/new
# edit_posts_path(:id) returns /posts/:id/edit (edit_post_path(10) returns /posts/10/edit)
# post_path(:id) returns /posts/:id (for instance, post_path(10) returns /posts/10)
# ======= # RESOURCE (singular) ======
resource :profile
# Sometimes, you have a resource that clients always look up without referencing an ID.
# intead of "/profile/1" it can be just "/profile"
# actions: show, new, create, edit, update, destroy
# GET /profile/new - profiles#new - return an HTML form for creating the profile
# POST /profile - profiles#create - create the new profile
# GET /profile - profiles#show - display the one and only profile resource
# GET /profile/edit - profiles#edit - return an HTML form for editing the profile
# PATCH/PUT /profile - profiles#update - update the one and only profile resource
# DELETE /profile - profiles#destroy - delete the profile resource
# ====== NAMESPACING & SCOPING =====
# If you want a specific path for a resource you can "contain" it inside a namespace
# This is common for private or admin areas of an app
namespace :admin do
resources :articles
end
# Results in:
# GET /admin/articles - admin/articles#index - admin_articles_path
# GET /admin/articles/new - admin/articles#new - new_admin_article_path
# POST /admin/articles - admin/articles#create - admin_articles_path
# GET /admin/articles/:id - admin/articles#show - admin_article_path(:id)
# GET /admin/articles/:id/edit - admin/articles#edit - edit_admin_article_path(:id)
# PATCH/PUT /admin/articles/:id - admin/articles#update - admin_article_path(:id)
# DELETE /admin/articles/:id - admin/articles#destroy - admin_article_path(:id)
# For organization purposes you can add ruby modules to the mix to move your controller in the admin space
scope module 'admin' do
resources :articles
end
# Your controller would then move to a module or in app/controllers/admin/articles_controller.rb instead of just app/controllers/.
# Inside the controller you would write the class a bit differently to compensate
# Admin::ArticlesController < ApplicationController
# ...
# end
# ====== NESTING ROUTES =====
# Simply nest like you would with a ruby block
# It's recommended to never nest 3 levels deep although it's possible.
resources :categories
resources :posts
end
# GET /categories/:category_id/posts
# posts#index
# display a list of all posts for a specific category
# category_posts_path(@category) # requires an instance of Category
# ----
# GET /categories/:category_id/posts/new
# posts#new
# return an HTML form for creating a new post belonging to a specific category
# new_category_post_path(@category) # requires an instance of Category
# ----
# POST /categories/:category_id/posts
# posts#create
# create a new post belonging to a specific category
# ----
# GET /categories/:category_id/posts/:id
# posts#show
# display a specific post belonging to a specific category
# category_post_path(@category, @post) # requires an instance of Category and Post
# ----
# GET /categories/:category_id/posts/:id/edit
# posts#edit
# return an HTML form for editing an post belonging to a specific category
# edit_category_post_path(@category, @post) # requires an instance of Category and Post
# ----
# PATCH/PUT /categories/:category_id/posts/:id
# posts#update
# update a specific post belonging to a specific category
# ----
# DELETE /categories/:category_id/posts/:id
# posts#destroy
# delete a specific post belonging to a specific category
# category_post_path(@category, @post), method: :delete # requires an instance of Category and Post
# ====== ROUTING CONCERNS ======
# Routing concerns allow you to declare common routes that can be reused inside other resources and routes.
concern :commentable do
resources :comments
end
# or
resources :comments, concerns: :commentable # this can be an array too i.e. [:commentable, :taggable]
# the above is equivelant to
resources :messages do
resources :comments
end
resources :articles do
resources :comments
resources :taggable, only: :index
end
# ===== Adding More RESTful Actions ====
# You can extend the default resources and resource to include additional restful and non-restful routing
resources :photos do
member do
get 'preview'
end
end
# This will recognize /photos/1/preview with GET, and route to the preview action of PhotosController, with the resource id value passed in params[:id]. It will also create the preview_photo_url and preview_photo_path helpers.
# Adding Collection Routes
resources :photos do
collection do
get 'search'
end
end
# ===== Non-Resourceful Routes ====
# A quick way to add routing for virtually any one-off path you need
get 'my/:id', to: 'users#dashboard'
# my/1
# ===== Defaults ==== #
# Only want to return JSON or some form of media? (jpg, mp4, etc...)
get 'users/:id', to: 'users#show', defaults: { format: 'json' }
# Rails would match users/1 to the show action of UsersController, and set params[:format] to "json".
# ===== NAMING ROUTES ====
# You can name a route whatever you please even if it doesn't match controller or path logic
# Use the as: method to pass a symbol of the name you wish to use
get 'exit', to: 'sessions#destroy', as: :logout
# If you want to overide parts of a resource you can by passing a named route first
get ':username', to: 'users#show', as: :user
resources :users
# This will define a user_path method that will be available in controllers, helpers, and views that will go to a route such as /bob. Inside the show action of UsersController, params[:username] will contain the username for the user. Change :username in the route definition if you do not want your parameter name to be :username.
# Part 2 coming soon !
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment