Codeigniterのバリデーション機能でデータベースにアクセスする方法


現在、Codeigniterを使って、WEBアプリケーションを開発中のYOUKIです。

フォームで入力されたデータが正しいものかチェックする処理を書いていたのですが、そのデータがユニークなのかチェックするという部分で躓きました。

なぜ躓いたのかというと、バリデーションに関する処理をコントローラーの中に書くのであれば、あっさりとクリア出来ているところだったのですが、モデルの中に書きたいというこだわりがあったんです。

本記事の情報は、Codeigniterの3.1.0バージョンを前提に書いています。それ以前やそれ以降のバージョンは確認していません。

Codeigniterのバリデーション機能について

Codeigniterでは、フォームから送信された情報の正当性をチェックするための機能が用意されています。また、こういう処理の事をバリデーションと呼びます。

Codeigniterのバリデーション機能を利用するには、Form_validationというクラスが用意されていますので、こちらを利用する事になります。

基本的な使い方は、以下のページでサンプルコードを交えながら説明されています。

http://codeigniter-jp.github.io/user_guide_src_ja/libraries/form_validation.html

今回の説明したいテーマ

Codeigniterのバリデーション機能を使う方法は、基本的に公式ページで確認する事が出来ますので、そちらを見ていただきたいと思っています。

今回、僕が書きたいのは、データベースに格納されているデータとフォームから入力されたデータを照らし合わせる場合などの話になります。

そして、今回はモデルでバリデーションを完結させる場合のパターンを説明していきます。

コントローラーのサンプル

Userというコントローラーを作成しました。

もし、POSTされていれば、モデルに記述されているメソッドを呼び出し、バリデーションの処理を行います。そして、バリデーションが成功した場合、モデルのデータベースに登録する処理を呼び出します。そして、バリデーションなどの結果を問わず、ビューを表示する仕様にしています。

モデルのサンプル

User_modelというモデルを作成しました。

バリデーション処理を行うメソッドとPOSTされたデータをデータベースに書き込むメソッドを用意しました。

ビューのサンプル

create_user_form.phpというフォーム用のビューを作成しました。基本的にFormヘルパーを使って、HTMLを生成しています。見た目は以下のようになります。

Codeigniterのビュー

ちなみにバリデーションの処理でエラーが発生すると、以下のように出力される仕様にしています。

Codeigniter バリデーションのエラー

入力データの重複をチェックしたい場合

会員登録などの処理を行う場合、IDの重複をチェックしたいと状況になる事が、必ずと言ってもいいほどにあると思います。出来るのであれば、バリデーション処理の時にまとめて行いたい。でも、どうすればいいのだろうか?と疑問を持つと思います。

元々、Form_validation.phpで定義されているルールになりますが、is_uniqueというものが用意されています。is_uniqueを使えば、すでに同じ値が存在しているのかをチェックする事ができ、存在している場合はエラーが返ってきます。

使い方は以下のようになります。

User_modelのコードを改変したのですが、is_unique[user.username]という部分が追加コードになります。

is_unique[table_name.field_name]という風な記述になります。[]の中は、どのテーブルのどのフィールドなのかという範囲を指定しているわけです。

その他の場合

Codeigniterでは、データベースにアクセスするようなルールがis_uniqueしかありません。

例えば、ログイン処理を実装するとして、POSTされたパスワードが正しいのかをチェックするルールが欲しいとします。

そこで、コールバック機能を利用し、新たなルールを作成するという解決方法があります。

コールバック機能のサンプル

Userコントローラーにis_match_passwordというメソッドを追加しました。

Userモデルにget_passwordというメソッドを追加しました。詳しい処理は省略します。

そして、Userモデルのルール定義を変更しました。

callback_is_match_passwordという記述を追加したのですが、先頭にcallback_というプリフィックスを書く事で、これはコールバック用のメソッドだと伝える事ができます。そして、コントローラーに記述しているis_match_passwordを呼び出します。

やっと本題に入れるのですが、このコールバック用のメソッドをモデルに書く事は出来ないのか?というとこで、僕は躓いたわけです。可能であれば、バリデーション用のモデルとか作りたいわけです。

具体的な処理をモデルに書いておいて、それを呼び出すだけのコールバック用のメソッドをコントローラーに定義する事もできますが、それは気持ち悪いので嫌でした。

オブジェクトとメソッド名を渡す方法

このような配列を渡す事で特定オブジェクトのメソッドを呼び出させる事が可能になります。

 

ところが、この書き方は間違いになります。この書き方の場合、set_message()でセットしたメッセージが正しく表示されません。以下が正しいコードになります。

 

これは公式情報でも触れられている部分です。正しくない書き方でも動作してしまうようです。ちなみに以下のページで今回のケースの事が触れられています。

http://codeigniter-jp.github.io/user_guide_src_ja/libraries/form_validation.html#id15

 


コメントを残す