Userコントローラの作成

まずは、ログイン時の謎のポエムをなんとかしましょう。

Userコントローラの自動生成

ユーザの情報を表示するためのコントローラとして、userコントローラというのを作ることにします(userモデルと名前を一致させておきます)。例によってscript/generateで自動生成します。

% script/generate controller user

生成されたもののうち、app/controllers/user_controller.rb がコントローラの定義です。まだ中身は空っぽ。

class UserController < ApplicationController
end

ここに、ユーザの情報(名前とか発言内容とか)を表示を行うためのメソッドを書いていきます。


コントローラのリファレンスはここ(日本語、UTF-8)とかここ(英語)にありますので、必要に応じて参照しながら書いていきます。

indexメソッドの記述

まず、ユーザの情報を表示する index メソッドを作ります。
http://localhost:3000/user/?id=NeoCat
もしくは
http://localhost:3000/user/index/NeoCat
のようにユーザのログイン名が指定された場合にはそのユーザの情報を表示し、
http://localhost:3000/user/
指定なしだとログイン中のユーザを表示する、という感じにしてみます。

URLのコントローラ名の後に何も指定されなかった場合、indexメソッドが呼ばれます。そこで、下記のメソッドをUserControllerに加えます。

class UserController < ApplicationController
  def index
    redirect_to(:controller => :account, :action => :login) and return if !logged_in?

    if params[:id]
      @user = User.find_by_login(params[:id])
      render :text => "not found" and return unless @user
    else
      @user = current_user
    end
  end
end

コントローラでやることはこれだけです。実際の表示するものの指定はビューの中でやりますので、ここではロジック部分のみを書きます。

中身の説明

まず、ユーザがログイン中であるかを確認し、ログインしていなかった場合は account/login にリダイレクトさせます。and returnはここでメソッドの処理を終わらせるためです。


次に、ビューに表示すべきユーザを渡すための処理を行います。@つきの変数は、ビューの内部でもアクセスできるようになります。ここでは@userを使って、ユーザ情報を渡します。


if文に出てくる params は渡された情報を示すハッシュです。params[;id]には http://localhost:3000/user/index/NeoCat のようにアクセスされた場合、NeoCatが入ります。URLの末尾に ?id=NeoCat と指定された場合も同じです。

この指定があれば、それをログイン名に持つユーザを検索します(idっていう名前はちょっと変だが)。User.find_by_loginというメソッドはフィールド名からRailsが自動生成したもので、文字通り引数に指定されたlogin名を持つユーザをusersテーブルから一人検索してくれます。この仕掛けはActiveRecordというもので、O/Rマッピングを提供してくれます。find*についてはid:elm200:20070316:1174044163あたりにいろいろな書き方が載ってます。

見つからなかった場合はnilになりますので、render_to メソッドを使って "not found"という文字をレンダリングし、処理を中止します。この場合ビューは呼び出されません。


idが指定されていなかった場合は、current_userを代入しておきます。current_userにはログイン中のユーザがいればUserクラスのインスタンスが代入されています。


renderもredirect_toも指定せずにメソッドを抜けると、自動的に app/views/user/index.rhtml の内容がレンダリング対象になります(userはコントローラ名、indexはメソッド名)。とりあえずこのファイルに

<%= @user.login %> 

とだけ書いて、ログイン名だけを表示するようにしておきます。

accountコントローラの変更

なお、ログイン後にポエムがでるのは、app/controllers/account_controller.rbの中で account/index にリダイレクトしているためです。これを、今作った user/index に飛ばすようにしましょう。
同ファイルの以下の部分を変更します。3カ所くらいあります。

      redirect_back_or_default(:controller => '/account', :action => 'index')
                                              ↓
      redirect_back_or_default(:controller => '/user', :action => 'index')

また念のため、ポエムをレンダリングしている本体であるaccount_controller.rbのindexメソッドを書き換えて

  def index
    if logged_in?
      redirect_to(:controller => '/user', :action => 'index')
    else
      if User.count > 0
        redirect_to(:action => 'login')
      else
        redirect_to(:action => 'signup')
      end
    end
  end

のように、適当な場所にリダイレクトするようにしておきます。
これでもうポエムの入っている views/account/index.rhtml は不要なので、消してしまいましょう。:-P

動作テストしてみる

これで、ログインしてみたり http://localhost:3000/user/http://localhost:3000/user/index/ユーザ名 にアクセスしてみると、上記の動作を試すことが出来ます。


次に、もうちょっとちゃんとビューの中身を作っていきます。