Topic: Jukebox application with Rails 2.0.2 + permalink + counter cache

Jukebox application with Rails 2.0.2 + permalink + counter cache

1.- rails jukebox -d mysql

2.- cd jukebox

3.- vi config/database.yml

4.- rake db:create:all
[ If you see a message about Database already Exists you can always clear the databases with the rake command: rake

db:drop:all ]

5.- ruby script/generate scaffold Artist name:string permalink:string albums_count:integer   

6.- ruby script/generate scaffold Album artist:references title:string permalink:string

7.- Edit your db/migrate 001_create_artists migration file to initialize the counter cache for artists_count and add the

index for the permalink column.

  def self.up
    create_table :artists do |t|
      t.string :name
      t.string :permalink
      t.integer :albums_count, :default => 0

      t.timestamps
    end
    add_index :artists, :permalink
  end


8.- Similar process for the 002_create_albums migration file, we need to add the index for the permalink column.
  def self.up
    create_table :albums do |t|
      t.references :artist
      t.string :title
      t.string :permalink

      t.timestamps
    end
    add_index :albums, :permalink
  end


9.- rake db:migrate

10.- delete the public/index.html and update your config/routes.rb file with the default route to the artists controller:

map.root :controller => 'artists'

ActionController::Routing::Routes.draw do |map|
  map.root :controller => 'artists'

  map.resources :albums
  map.resources :artists
....
end


11.- Update the Model files for our asociations and allow counter_cache.
Edit the app/models/artist.rb
  has_many :albums

Edit the app/models/album.rb
  belongs_to :artist, :counter_cache => true


12.- Edit your Artists views and delete or comment part of the form to insert or edit Artists count since is a counter cache,

we don't need to update manually

From the app/views/artists/new.html.erb and app/views/artists/edit.html.erb remove the Artists_count field...

<!--
  <p>
    <b>Artists count</b><br />
    <%= f.text_field :artists_count %>
  </p>

-->


13.- Lets prepare to for Permalink:
Add to your Artist model file app/model/artist.rb:
class Artist < ActiveRecord::Base
  has_many :albums

  def to_param
    permalink
  end

end


Same rule appy for the app/model/album.rb:
class Album < ActiveRecord::Base
  belongs_to :artist, :counter_cache => true

  def to_param
    permalink
  end

end


14.- To make this work lets update the Artist controller file app/controller/artists_controller.rb

Replace: Artist.find with Artist.find_by_permalink everywhere except the index action.

Same rule apply to the Albums controller app/controller/albums_controller.rb:

Replace: Album.find with Album.find_by_permalink everywhere except the index action.

15.- Edit the New and Edit file for the Albums model: app/views/albums/new.html.erb

    <b>Artist</b><br />
    <%#= f.text_field :artist %>
    <%= collection_select(:artist, :artist_id, Artist.find(:all), :id, :name, {:prompt => true}) %>
  </p>

Now for the second file app/views/albums/edit.html.erb:
    <b>Artist</b><br />
    <%#= f.text_field :artist %>
    <%= collection_select(:artist, :artist_id, Artist.find(:all), :id, :name, {:prompt => false}) %>
  </p>

This change will retrieve the list of the current selected Artists in the select box.

16.- The last step some required validations for the appropiate operation of the application:

For the Artists: app/models/artist.rb

  validates_presence_of :name
  validates_presence_of :permalink

  validates_uniqueness_of :name
  validates_uniqueness_of :permalink


For the Albums: app/models/album.rb:
  validates_presence_of :artist
  validates_presence_of :title
  validates_presence_of :permalink

  validates_uniqueness_of :title
  validates_uniqueness_of :permalink


That's All folks go a head and start the web server...
ruby script\server

Feel free to navigate in your application at:
http://localhost:3000/artists
http://localhost:3000/albums

Features:
The albums page will be automatically linked to the list of available artists.
Both models can be browse via permalink which is really really cool.
Rails validations will take care of the uniqueness of the permalink & title of the artists & Albums
Yes just like any other rails applications created in just 2 minutes...

Things to do:
Modify the app/views/albums/index.html.erb because the line: <td><%=h album.artist %></td> does not retrieve anything.
Fix a little bug somewhere in the Albums form views... the counter_cache does not work from the web browser but It works from the script console.

For Part II of this tutorial:
Migrate the configuration to a Nested scenario /artists/some_artist/albums/some_album ...

Happy new Year 2008 Go -Rails Go !!!
Din00z.

Last edited by dinooz (2008-03-03 10:42:01)

Re: Jukebox application with Rails 2.0.2 + permalink + counter cache

A couple of comments:

On step 12, it's the albums count we're removing, not the artists count.

On step 15, putting <%= collection_select(:artist, [etc...] will trigger a validation error. I found that using <%= collection_select(:album, :artist_id, Artist.find(:all) [etc...] instead fixed this.

I did the albums index fix as well:

In the index method of the index action in controllers/albums_controller.rb, change @albums = Album.find(:all) to @albums = Album.find(:all, :include => :artist). Now, in views/albums/index.html.erb, change <%=h album.artist %> to <%=h album.artist.name %>.

I was very happy with this turorial and learnt a lot. It has been the only one I've tried so far that's worked with Rails 2.0.2. Thanks a lot smile