Rails に(再)挑戦 3日目 - 更新順序で並び替え
2006-10-04
昨日はビューの見栄えを変えるところまで。 今日はロジック(モデルとコントローラ)に手を加えてみよう。 今の状況だと、各ページは 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
これで、新規に作ったページや更新したページが、上に表示されるようになった。