入力されたパスワードの再確認

080705修正

通りすがりさんの言うとおりでした。

  validates_confirmation_of :password
  attr_accessor             :password_confirmation

これだけで解決。

以下無知な無駄orz。


良くあるアレなんですが、入力されたパスワードの再確認をしたい場合がちょっと困った
とりあえず手元の文献には解消が載ってなかったのでがんばって解決してみる
(こういうのって後でもっとスマートなの文献で見つけてへこむんだよね・・・)

(=== View ===)
		パスワード: <%= password_field 'account' , 'password' >
		パスワード再入力:<%= password_field 'account' , 'rpassword' >

rhtmlからこんな感じのフォームで投稿されたパスワードと再入力データがあったとする
処理的には

	POST -> Controller -> Model(ここでValidate検証) -> 問題がなかったらDBに記録

となっているが、ModelにはDBに記録されるであろうオブジェクトしか存在しないため、(passwordはあるがrpasswordは存在しない)

(=== Controller ===)
    @account = Account.new(params[:account])

こんな感じに受け取ったデータをそのままModelに投げると、両方がModelに投げ込まれ、rpasswordは存在しないと怒られる。

Controllerで検証してエラーを返すこともできるがValidateで出す他のエラーと一緒に出したい。

解決方法その1 Controllerから無理やりValidateに追加(ちょっと問題あり)

送られてくるPOSTを2つのオブジェクトに分ける

(=== View ===)
		パスワード: <%= password_field 'account' , 'password' >
		パスワード再入力:<%= password_field 'account_chk' , 'rpassword' >

Controllerで検証して問題があったらController側からValidateに突っ込む

(=== Controller ===)
    @account = Account.new(params[:account])
	@account.save
	if params[:account][:password] != params[:account_chk][:rpassword]
	  @account.errors.add(:password, "が再入力された値と一致しません。")
	  @account.destroy
	end

これで表示されるが問題点がいくつかある(解決方法はあるかも?)
・普通のvalidateはsaveの時点で記録される前に検証されてはじくが、この場合saveされてからじゃないとダメなので、エラーがあった際はDBから削除する必要がある。結果として記録しないはずのDBアクセスが発生するので望ましくない
・rpasswordに記録された内容は消える

解決方法その2 Model側にデータ追加(こっちを採用)

accountオブジェクトとしてPOST

(=== View ===)
		パスワード: <%= password_field 'account' , 'password' >
		パスワード再入力:<%= password_field 'account' , 'rpassword' >

そのままだと「rpasswordが無い」と怒られるので外からアクセスできる変数としてrpasswordをModelに準備し、valideteで検証する

(=== Model ===)
  attr_accessor :rpassword
  attr_accessor :chkdata #注1
  
  def validate
    if self.rpassword != self.password && self.chkdata==true
      errors.add(:rpassword, "が再入力された値と一致しません。")
    end
  end    

外から来たデータをそのままModelに突っ込んでセーブ

(=== Controller ===)
    @account = Account.new(params[:account])
    @account.chkdata = true #注2
	@account.save

・注1
この際の注意点は、投稿時はrpasswordが必ず存在するのでいいが、それ以外の書き換え時にrpasswordが必要になってしまう。そのため、投稿時のみrpasswordをチェックをするようにしないといけないので chkdataフラグを用意し、投稿時は注2の時点でtrueにすることで再入力チェックをONに、投稿時以外は再入力をチェックしないようにする。

これでとりあえず何の問題も無くきれいに動きました
他にもきっといい方法があるに違いないけど、まあきれいに解決したのでよしw