avosalmonのブログ

プログラミングやWebデザイン、DTMについて調べたことをメモってます。プログラマー兼ベーシストです。

【Rails】flashとflash.nowの違い

flashflash.nowではflashメッセージの有効期間が異なります。

flash
次のHTTPリクエストまでメッセージが有効。
次のリクエストが終了した時点でメッセージは消える。
redirect_toした先の画面でメッセージを表示したい時に使用する。
flash.now
現在のHTTPリクエストでのみメッセージが有効。
次のリクエストが終了した時点でメッセージは消える。
renderで表示する画面にメッセージを表示したい時に使用する。


renderで画面表示している(新しいHTTPリクエストは送信されない)にも関わらずflashを使用すると、1つ先の画面でもflashメッセージが表示されてしまう。
renderの場合はflash.nowを使用する。


参考記事
[Rails] flash.now[:notice]とflash[:notice]の違い - 拝啓、シーシュポス

【Rails】都道府県を扱うgem

フォームのselectタグで都道府県を扱う場合、collection_selectを使っても
DBに都道府県のマスタを登録しておく必要があるので面倒です。

jp_prefectureというgemを使うと、DBにマスタを登録せずに都道府県を簡単に扱うことができます。


こんな感じでJpPrefecture::Prefecture.allを呼ぶだけで全都道府県の配列を取得できます。

<%= f.collection_select :pref, JpPrefecture::Prefecture.all, :name, :name %>


参考記事
jp_prefecture という都道府県を扱う gem を作った - 暇人じゃない

[Rails4] DBに暗号化されたパスワードを保存する

暗号化されたパスワード用のカラム名をpassword_digestにする

migration例

class AddPasswordDigestToUsers < ActiveRecord::Migration
  def change
    add_column :users, :password_digest, :string
  end
end


暗号化用のハッシュ関数として、bcrypt-rubyをGemfileに追加

gem 'bcrypt-ruby', '3.1.2'


Modelクラスに、has_secure_passwordを追加するだけで以下のことを勝手にやってくれる
→formで確認用パスワードを要求
→最初に入力したパスワード(password)と確認用パスワード(password_confirmation)が一致するかチェック
→暗号化したパスワードをDBに保存
※passwordとpassword_confirmationは、Model内に仮想的に作られるカラムで、実際のテーブルには存在しないカラムである

Model例

class User < ActiveRecord::Base
  .
  .
  .
  has_secure_password
end

has_secure_passwordが如何に便利か

Railsチュートリアルより抜粋

(パスワードの存在検証と確認はhas_secure_passwordによって自動的に追加されます。)

次に、password属性とpassword_confirmation属性を追加し、パスワードが存在することを要求し、パスワードとパスワードの確認が一致することを要求し、さらにauthenticateメソッドを使用して、暗号化されたパスワードとpassword_digestを比較してユーザーを認証するという多くの手順が必要です。この実装が唯一手間のかかる箇所ですが、最新のRailsではhas_secure_passwordを使用するだけでこれらの機能をすべて自由に利用できます。

has_secure_password
データベースにpassword_digestカラムを置くという条件さえ守れば、上のメソッドをモデルに追加するだけで新規ユーザーの作成と認証をセキュアにすることができます。