A resource is a route that maps requests made with a HTTP verb to an action in a controller. Here is what a regular resource "resources :clubs" looks like and use command rake routes in the terminal to view:
// ♥ rake routes Prefix Verb URI Pattern Controller#Action clubs GET /clubs(.:format) clubs#index POST /clubs(.:format) clubs#create new_club GET /clubs/new(.:format) clubs#new edit_club GET /clubs/:id/edit(.:format) clubs#edit club GET /clubs/:id(.:format) clubs#show PATCH /clubs/:id(.:format) clubs#update PUT /clubs/:id(.:format) clubs#update DELETE /clubs/:id(.:format) clubs#destroy
We use nested resources to reflect our has_many relationship between our models in the routes, and ultimately our URLs. Doing this allows us to keep our code DRY(don't repeat yourself), which is a software engineering principle and best practice.
Here's an example of nested routes, that have a "has_many" relationship. A club has many fighters and a fighter belongs to a club.
#app/models/club.rb class Club < ActiveRecord::Base has_many :fighters end #app/models/fighter.rb class Fighter < ActiveRecord::Base belongs_to :club end
#config/routes.rb Rails.application.routes.draw do resources :clubs, only: [:show] do resources :fighters, only: [:show, :index] end end
Now that we have our nested resources, we don't have to write code like this in our clubs_controller.rb file:
def fighters_index @club = Club.find(params[:id]) @fighters = @club.fighters render template: 'fighters/index' end
Instead, staying true to a best practice principle, DRY, in our fighters_controller.rb file we write:
#app/controllers/fighters_controller.rb def index if params[:club_id] @fighters = Club.find(params[:club_id]).includes(:clubs).fighters else @fighters = Fighter.all end end
Notice: We switched to fighters_controller.rb file, to keep a best practice principle, Separation of Concerns, implemented in our code.
Using Nested URL Helpers
Our URLs and route helpers have changed because we've nested the resources(don't forget to add _path or _url):
- view a club's fighters - club_fighters_path
- view a club's specific fighter - club_fighter_path
// ♥ rake routes Prefix Verb URI Pattern Controller#Action club_fighters GET /clubs/:club_id/fighters(.:format) fighters#index club_fighter GET /clubs/:club_id/fighters/:id(.:format) fighters#show club GET /clubs/:id(.:format) clubs#show