Masatoshi Nishiguchi

Nested routes in Rails

This is my memo on Nested routes in Rails.

Nested Routes

Rails.application.routes.draw do
  ...
  resources :artists do
    resources :songs
  end
  ...
$ rake routes | grep song
    artist_songs GET    /artists/:artist_id/songs(.:format)          songs#index
                 POST   /artists/:artist_id/songs(.:format)          songs#create
 new_artist_song GET    /artists/:artist_id/songs/new(.:format)      songs#new
edit_artist_song GET    /artists/:artist_id/songs/:id/edit(.:format) songs#edit
     artist_song GET    /artists/:artist_id/songs/:id(.:format)      songs#show
                 PATCH  /artists/:artist_id/songs/:id(.:format)      songs#update
                 PUT    /artists/:artist_id/songs/:id(.:format)      songs#update
                 DELETE /artists/:artist_id/songs/:id(.:format)      songs#destroy

Example of a new form

<h2>New Song</h2>

<%= form_for [@artist, @song] do |f| %>
  <%= f.label :title %>
  <%= f.text_field :title %>

  <%= f.label :album %>
  <%= f.text_field :album %>

  <%= f.label :preview_url %>
  <%= f.text_field :preview_url %>

  <%= f.submit %>
<% end %>
class SongsController < ApplicationController
  ...
  # GET    /artists/:artist_id/songs/new
  def new
    @artist = Artist.find(params[:artist_id])
    @song = Song.new
  end

  # POST   /artists/:artist_id/songs
  def create
    @artist = Artist.find(params[:artist_id])
    @song = @artist.songs.create(song_params)
    redirect_to @artist
  end
  ...
class SongsController < ApplicationController
  ...
  # GET    /artists/:artist_id/songs/new
  def new
    @artist = Artist.find(params[:artist_id])
    @song = @artist.songs.new
  end

  # POST   /artists/:artist_id/songs
  def create
    @artist = Artist.find(params[:artist_id])
    @song = Song.new(song_params.merge(artist: @artist))
    if @song.save
      flash[:success] = "A song added to #{@artist.name}"
      redirect_to @artist
    else
      render :new
    end
  ...

Misc

Passing data through params

Rails Named Routes: Path Vs. URL


References

Many-to-many relationship in Rails

This is my memo on Many-to-many relationship in Rails. Adding a many to many relationship between the following two models.

Create a migration file to create a join table.

rails g model Favorite user:references song:references

db/migrate/20160629144158_create_favorites.rb

class CreateFavorites < ActiveRecord::Migration
  def change
    create_table :favorites do |t|
      t.references :song, index: true, foreign_key: true
      t.references :user, index: true, foreign_key: true

      t.timestamps null: false
    end
  end
end

The join table

app/models/favorite.rb

class Favorite < ActiveRecord::Base
  belongs_to :song
  belongs_to :user
end

Two models access each other through the join table.

app/models/user.rb

class User < ActiveRecord::Base
  ...
  has_many :favorites, dependent: :destroy
  has_many :songs, through: :favorites
  ...

app/models/song.rb

class Song < ActiveRecord::Base
  ...
  has_many :favorites, dependent: :destroy
  has_many :users, through: :favorites
  ...

References