コントローラを作る
前回までに,ビューを作るかデフォルトを修正するだけで,Wavesは様々なことができることを示しました。今回は一歩進んで独自のモデルやコントローラを作ってみます。
まずはWordコントローラを作ってみましょう。前回,controllers/default.rbを書き換えて,nameフィールドではなく,idフィールドでレコードを探すように修正しましたが,これをWordモデル限定の動作にして,他のモデルはWavesのデフォルトである「nameフィールドの値でレコードを見つける」にしたいからです。
default.rbを元に戻す
まず,controllers/default.rbの動作を元に戻してください。
default.rbの前回修正部分
def all; model.order(:created_on.desc).all; end
def find( name ); model[ :id => name ] or not_found; end
default.rbの動作を戻す
def all; model.all; end
def find( name ); model[ :name => name ] or not_found; end
この変更により,Twアプリケーションは正常に動作しなくなります。そこで,以下の修正を行ってください。
Wordコントローラを作る
Wordコントローラを作る
rake generate:controller name=word
生成されたcontrollers/word.rbを上記の逆に修正します。これでWordモデルの検索動作だけがidフィールドに対して行われます。Twアプリケーションも無事動くようになるはずです。
WavesのREST動作
前回も簡単に述べましたが,Wavesがデフォルトで提供しているREST動作やnameフィードでレコードを検索する動作は,デフォルトルールとしてconfigrations/mapping.rbで指定されています。「include Waves::Mapping::PrettyUrls::RestRules」と「include Waves::Mapping::PrettyUrls::GetRules」です。前者がREST動作を規定して,後者がnameフィールドによる検索を規定しています。デフォルトのルールが不満なら,mapping.rbからルールを削除して,自前で記述することも可能です。
include Waves::Mapping::PrettyUrls::RestRule
RestRuleをincludeすると,以下の3つの処理が使えるようになります。
POST /リソース # 新しいリソースを追加する
POST /リソース/名前 # 指定の名前のリソースを更新する
DELETE /リソース/名前 # 指定の名前のリソースを削除する
Twアプリケーションで'/words'というURLに対してフォームの内容をPOSTすると,新規にWordレコードが生成されるのが,RestRuleの機能です。
include Waves::Mapping::PrettyUrls::GetRules
GetRulesをincludeすると,以下の処理が使えるようになります。
/リソース(複数形) # リソースの全リストを取得する
/リソース/名前 # 指定の名前のリソースを取得する
/リソース/名前/editor # 指定のリソースの編集画面を呼び出す
Twアプリケーションで'/words'というURLを呼び出すと,Wordテーブルの全レコードを取得して,templates/word/list.mabが呼び出されるのがGetRulesの機能です。
ユーザと関連を追加する
Twアプリケーションは今のままではアクセスした人の発言がそのままリストされるだけなので,ユーザ毎に発言をまとめる機能を追加します。そのためにUserモデルを追加して,ユーザと発言の関連も追加します。
Userモデルを追加する
次に認証を追加することを考慮して,ユーザ名とパスワードを格納するテーブルを作ります。
Userテーブルのマイグレーションを生成する
rake schema:migration name=add_user
schema/002_add_users.rbを以下のように修正します。
Userテーブルのマイグレーションを修正する
class AddUsers < Sequel::Migration
def up
create_table :users do
primary_key :id
text :name, :unique => true, :null => false
text :password, :null => false
end
add_column :words, :user_id, :foreign_key, :table => :users
end
def down
drop_table :users
drop_column :words, :user_id
end
end
Usersテーブルはid,name,passwordフィールドを持ちます。nameフィールドはユニークでなければなりません。また,発言は発言者に属するので,Wordsテーブルにuser_idフィールドを追加します。「rake schema:migrate」でマイグレーションを実行しましょう。テーブルが生成されます。次にWordモデルとUserモデルを作り,両者の関連を設定します。
WordモデルとUserモデル
rake generate:model name=word rake generate:model name=user
models/word.rbを以下のように修正します。
Wordモデルにmany_to_oneを設定する
module Tw
module Models
class Word < Sequel::Model(:words)
many_to_one :user, :class=>Tw::Models::User
after_create do
set(:created_on => Time.now) if columns.include? :created_on
end
before_save do
set(:updated_on => Time.now) if columns.include? :updated_on
end
end
end
end
一人のユーザが複数の発言を所有するので「many_to_one :user, :class=>Tw::Models::User」が必要になります。Railsと異なり,クラスまで指定する必要があります。逆にUserモデル(models/user.rb)には,「one_to_many :words, :class=>Tw::Models::Word」を追加してください。これでUserモデルとWordモデルの間に関連が設定されました。

