Rails に(再)挑戦 3日目 - 更新順序で並び替え
昨日はビューの見栄えを変えるところまで。 今日はロジック(モデルとコントローラ)に手を加えてみよう。 今の状況だと、各ページは id 順(つまり古い順)に並んでいる。 これを、更新した順(新しい順)に表示されるようにする。
更新順に並べるために、まずは Page クラスへ更新時刻とついでに作成時刻を追加する。
マイグレーション
migration の機能を使って、データベースの pages テーブルに更新時刻と作成時刻を追加する。 マイグレーションファイルの雛形は、 script/generate で生成できる。
$ script/generate migration AddUpdatedToPage exists db/migrate create db/migrate/002_add_updated_to_page.rb
pages テーブルに対して、生成時刻 (created) と更新時刻 (updated) のカラムを追加する。 検索速度を速くするために、それぞれにはインデックスを張るようにしている。
$ vi db/migrate/002_add_updated_to_page.rb class AddUpdatedToPage < ActiveRecord::Migration def self.up add_column :pages, :created, :time add_index :pages, :created add_column :pages, :updated, :time add_index :pages, :updated end def self.down remove_column :pages, :created remove_column :pages, :updated end end
rake コマンドを使って、データベースのスキーマを修正する。
$ rake migrate (in /home/machu/work/misc/rails/rn) == AddUpdatedToPage: migrating ================================================ -- add_column(:pages, :created, :time) -> 0.0275s -- add_index(:pages, :created) -> 0.0084s -- add_column(:pages, :updated, :time) -> 0.0300s -- add_index(:pages, :updated) -> 0.0040s == AddUpdatedToPage: migrated (0.0734s) =======================================
コントローラの修正
データベースの準備ができたので、NoteController に手を加える。
一覧表示 (list) にて、更新時刻の新しい順に並び替えるようにオプション(:order => 'updated DESC')を指定する。 それから、新規作成 (create) と更新 (update) の時に、生成時刻と更新時刻と設定するようにした。
$ vi app/controllers/note_controller.rb class NoteController < ApplicationController def list @page_pages, @pages = paginate :pages, :per_page => 10, :order => 'updated DESC' end def create @page = Page.new(params[:page]) @page.created = Time.now @page.updated = Time.now if @page.save # 中略 end end def update @page = Page.find(params[:id]) @page.updated = Time.now if @page.update_attributes(params[:page]) # 中略 end end end
ビューの修正
せっかく生成時刻と更新時刻を記録するようにしたので、画面にも表示するようにビューを修正する。 具体的には Page の共通ビュー (_page.rhtml) に下記の2行を追加している。 このビューは一覧表示 (list) と個別表示 (show) で共通に使われるようにしているので、一箇所を変えれば一覧表示と個別表示の両方に反映される。 共通化しておいて良かった。
$ vi app/views/note/_page.rhtml created: <%= page.created.strftime('%Y-%m-%d %H:%M') if page.created %> updated: <%= page.updated.strftime('%Y-%m-%d %H:%M') if page.updated %>
データの移行
これまでに作られたページには生成時刻も更新時刻も含まれていない。 そこで、コンソール (script/console) を使って、既存のデータに生成時刻と更新時刻を設定する。 迷ったけど、とりあえず現在時刻を両者に設定することにした。
$ script/console Loading development environment. >> Page.find(:all).each do |page| ?> page.created = Time.now >> page.updated = Time.now >> page.save >> end
これで、新規に作ったページや更新したページが、上に表示されるようになった。