Railsメモ(17) : コントローラとビューを更新する
Artistモデルを作成し、SongモデルとArtistモデルの間に多対多のリレーションを作成したので、コントローラとビューも更新する。
最初に下記コマンドでひな形を作成する。今回はArtistの一覧を表示するindex
ページとArtist個別のshow
ページを作成する。
$ rails g controller Artists index show create app/controllers/artists_controller.rb route get 'artists/show' route get 'artists/index' invoke erb create app/views/artists create app/views/artists/index.html.erb create app/views/artists/show.html.erb invoke helper create app/helpers/artists_helper.rb invoke assets invoke coffee create app/assets/javascripts/artists.coffee invoke scss create app/assets/stylesheets/artists.scss
続いてconfig/routes.rb
を書き換える。
resources
を指定すると7つの基本アクションが追加されるが、以下のようにonly
で使用するアクションだけを指定することができるようだ。
Rails.application.routes.draw do #get 'artists/index' #get 'artists/show' resources :artists, only: [:index, :show]
$ rake routes Prefix Verb URI Pattern Controller#Action artists GET /artists(.:format) artists#index artist GET /artists/:id(.:format) artists#show …省略…
コントローラの編集
コントローラーのapp/controllers/artists_controller.rb
は下記のようにした。index
では全アーティストを、show
では個別のアーティストを取得する。ここでbefore_action
はアクションコールバックと呼ばれるもので各アクションの前で実行したい共通の処理を記述することができる。今回は、Navbarに検索用フォームを作成しているのでbefore_action
を使用して対応した(他にもっとよい方法があるのかも知れないが)。
class ArtistsController < ApplicationController before_action :navbar_ransack def index @artists = Artist.page(params[:page]) end def show @artist = Artist.find(params[:id]) end private def navbar_ransack @q = Song.ransack(params[:q]) end end
ビューの編集(views/artists)
app/views/artists/index.html.erb
は以下のようにアーティスト名と曲数を一覧で表示するようにする。アーティスト名にはリンクは貼り、曲数はartist.songs.size
で取得してみる。
<table class="table table-striped table-hover"> <thead> <tr> <th>Name</th> <th>Songs</th> </tr> </thead> <tbody> <% @artists.each do |artist| %> <tr> <td><%= link_to artist.name, artist_path(artist) %></td> <td><%= artist.songs.size %></td> </tr> <% end %> </tbody> </table> <%= paginate @artists %>
図は実際の出力例。
app/views/artists/show.html.erb
は、そのアーティストが関連する曲をリスト表示する。@artist.songs.each
でループをまわせば図のような出力になる。
<table class="table table-striped table-hover"> <thead> <tr> <th>Title</th> <th>Display artist</th> <th>ranking</th> <th>year</th> </tr> </thead> <tbody> <% @artist.songs.each do |song| %> <tr> <td><%= song.title %></td> <td><%= song.display_artist %></td> <td><%= song.ranking %></td> <td><%= song.year %></td> </tr> <% end %> </tbody> </table>
ビューの編集(views/songs)
app/views/songs/index.html.erb
も編集して、図のように複数アーティスト名がある文字列に対して個別にアーティストへのリンクを貼るようにしてみる。
いろいろと書き方はありそうだが、とりあえず以下のようにgsub!
で変換した後にhtml_safe
で出力する方法にしてみた。
…省略… <% @songs.each do |song| %> <tr> <td><%= song.title %></td> <td> <% song.artists.each do |artist| %> <% song.display_artist.gsub!(/#{artist.name}/) {link_to artist.name, artist_path(artist)} %> <% end %> <%= song.display_artist.html_safe %> </td> <td><%= song.ranking %></td> <td><%= song.year %></td> </tr> <% end %> …省略…
ビューの編集(views/layouts)
最後に、NavbarにArtist一覧表示のリンクを追加し、検索フォームを右端に表示するようにして終了。
…省略… <div class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <%= link_to 'Billboard', root_path, class: 'navbar-brand' %> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li><%= link_to 'Artist', artists_path %></li> </ul> <%= search_form_for @q, html: { class: 'navbar-form navbar-right' } do |f| %> <%= f.input :title_cont, label: false, placeholder: 'title' %> <%= f.input :display_artist_cont, label: false, placeholder: 'display_artist' %> <%= f.button :submit %> <% end %> </div> </div> </div> …省略…
これでアーティスト関連のページが表示できるようになったが、ログを見てみると大量のSQL文が実行されているので次ステップで対応してみる。
- 作者: すがわらまさのり,前島真一,近藤宇智朗,橋立友宏
- 出版社/メーカー: 技術評論社
- 発売日: 2014/06/06
- メディア: 大型本
- この商品を含むブログ (8件) を見る