Railsでモデルを使わないで入力チェックを行う

フォームでの入力値をチェックしたいのだが
入力値に対応するモデルがない場合など
モデル以外で入力チェックを行いたいことがあるかと思います。

かといってコントローラ内でチェックすると
・コントローラが太る
・テストがやり難い
などがあり、これも今一な感じです。

・・・で、ヘルパーに入力チェックを記入しました。
ヘルパーはビューから呼び出す物だ、というツッコミはご容赦ください(笑)

以下、画面、ソース、RSpecのテストです。
入力項目に対して入力必須チェックを行い、エラーであればメッセージを表示します。

■画面
f:id:UnderSourceCode:20130707102304j:plain

■コントローラ


class HomeController < ApplicationController
include HomeHelper

def index
@today = Date.today.strftime("%Y/%m/%d")
end

def search
redirect_to :action => "index" if !search_validate
end
end


コントローラでは、使用するヘルパーをincludeし、
searchアクション内でsearch_validate()メソッドを呼び出し
エラーであればindexアクションにRedirectしています。

テストをし易くするため、コントローラ内でRedirectを行い
次のヘルパーでは入力チェックとエラーメッセージの設定のみを行います。
(ヘルパーからでもRedirectできるが、テストから呼び出すとエラーとなる)


■ヘルパー


module HomeHelper
def search_validate
return false if !param_validate(:fromIC, "出発ICを入力してください")
return false if !param_validate(:toIC, "到着ICを入力してください")
return false if !param_validate(:datepicker, "出発日付を入力してください")
return false if !param_validate(:hour, "出発時間を入力してください")
return false if !param_validate(:minute, "出発時間を入力してください")
return false if !param_validate(:carType, "車種を入力してください")
return true
end

private
def param_validate(key, message)
if params[key] == ""
flash[:alert] = message
return false
end

return true
end
end


param_validateメソッド内で、フォームで入力した値をparamsより取得し
""(空)でないかをチェックしています。
入力されていない場合、Railsのflashにメッセージを設定しています。


■テスト


#coding:utf-8
require 'spec_helper'

describe HomeHelper do
params = nil

before(:each) do
params = Hash.new
params[:fromIC] = "東京"
params[:toIC] = "名古屋"
params[:datepicker] = "2013/07/08"
params[:hour] = "12"
params[:minute] = "45"
params[:carType] = "普通車"
stub!(:params).and_return(params)
end

describe "search_validate" do
it "出発ICが空だとエラー" do
params[:fromIC] = ""
result = search_validate
result.should eq(false)
flash[:alert].should eq("出発ICを入力してください")
end

it "到着ICが空だとエラー" do
params[:toIC] = ""
result = search_validate
result.should eq(false)
flash[:alert].should eq("到着ICを入力してください")
end

it "日付が空だとエラー" do
params[:datepicker] = ""
result = search_validate
result.should eq(false)
flash[:alert].should eq("出発日付を入力してください")
end

it "時間が空だとエラー" do
params[:hour] = ""
result = search_validate
result.should eq(false)
flash[:alert].should eq("出発時間を入力してください")
end

it "分が空だとエラー" do
params[:minute] = ""
result = search_validate
result.should eq(false)
flash[:alert].should eq("出発時間を入力してください")
end

it "車種が空だとエラー" do
params[:carType] = ""
result = search_validate
result.should eq(false)
flash[:alert].should eq("車種を入力してください")
end

it "全てが入力されているとOK" do
result = search_validate
result.should eq(true)
flash[:alert].should eq(nil)
end
end

end


ちょっと書き方が冗長な気もしますが(笑)、一応、入力必須チェックが
正しく動いているかはテストしています。


以上です。コントローラはできるだけ減らした方が
ユニットテストを書く上でも個人的には好みです。