Masatoshi Nishiguchi

Custom routes in Rails

This is my memo on Custom routes in Rails.

You are not limited to the seven routes that RESTful routing creates by default. If you like, you may add additional routes that apply to the collection or individual members of the collection. - Rails Guides

config/routes.rb

Rails.application.routes.draw do
  ...
  resources :songs do
    member do
      post 'add_favorite'
      delete 'remove_favorite'
    end
  end
  ...
end

app/controllers/songs_controller.rb

class SongsController < ApplicationController
  ...
  def add_favorite
    @song = Song.find(params[:id])
    @artist = @song.artist
    @song.favorites.create(user: current_user)
    redirect_to artist_path(@artist)
  end

  def remove_favorite
    @song = Song.find(params[:id])
    @artist = @song.artist
    @song.favorites.where(user: current_user).destroy_all
    redirect_to artist_path(@artist)
  end
  ...
$ rake routes | grep favorite
    add_favorite_song POST   /songs/:id/add_favorite(.:format)             songs#add_favorite
    remove_favorite_song DELETE /songs/:id/remove_favorite(.:format)          songs#remove_favorite

References

Creating models in Rails

This is my memo on Creating models in Rails.

Create models and migration files (database schema)

docs

rails generate model NAME [field[:type][:index] field[:type]

Migrate the database

$ rake db:migrate
== 20160624190709 CreateArtists: migrating ====================================
-- create_table(:artists)
   -> 0.0247s
== 20160624190709 CreateArtists: migrated (0.0248s) ===========================
...

In case, you need to reset the database, run

$ rake db:migrate:reset

Create a seed file and fill the database with sample database

require_relative './song_data.rb'
require_relative './artist_data.rb'

# Clear all the data in the database.
Song.destroy_all   # Dependent
Artist.destroy_all

# Get data from files.
song_data   = get_song_data()
artist_data = get_artist_data()

# Associate artist to his/her songs.
song_data.each_pair do |artist_name, songs|
  info = artist_data[artist_name]
  current_artist = Artist.create!({
    name:         info[:name],
    photo_url:    info[:photo_url],
    nationality:  info[:nationality]
  })

  songs.each do |song|
    Song.create!({
      title:        song[:title],
      album:        song[:album],
      preview_url:  song[:preview_link],
      artist:       current_artist
    })
  end
end
$ rake db:seed

Check if the data is successfully injected into the database.

$ rails c
>> Song.all
  Song Load (2.3ms)  SELECT "songs".* FROM "songs"
=> #<ActiveRecord::Relation []>
>> Artist.all.length
  Artist Load (2.3ms)  SELECT "artists".* FROM "artists"
=> 5
>> Song.all.length
  Song Load (2.1ms)  SELECT "songs".* FROM "songs"
=> 250
>>