cookieで前回アクセス時の情報を復元
クッキーの値をDBに格納しておき、
次回同じユーザがアクセスしたときに格納しておいた情報を参照できるようにするするためのベースの仕組みの試作を行ってみました。
テーブル定義
まず,cookieを保存しておくテーブルは以下のように定義します。
class CreateVisitors < ActiveRecord::Migration def self.up create_table :visitors do |t| t.column :value, :string, :limit => 32, :null => false t.column :hashed, :string, :limit => 32, :null => false t.column :expired, :date, :null => false t.timestamps end end def self.down drop_table :visitors end end
カラムとして以下のものを定義しています。
cookieの値
cookieの有効期限
モデル
以下のようにcookieのモデルを定義。cookieの取得、生成を行うfind_from_cookieメソッドを定義しました。
class Visitor < ActiveRecord::Base # サイト訪問者のcookieを記録するモデル # +value+(クッキーの値), +hashed+(照合用のハッシュ値のクッキー値), +expire+を含むモデル attr_accessor :must_send public # cookie情報をもとに行を検索 # 未作成または、期限まで1ヶ月以内であれば新規生成 # 有効期限が近ければ更新 def self.find_from_cookies(cookies) visitor = if cookies[:visitor] then value = cookies[:visitor] Visitor.find_by_value(value) else nil end new_visitor = if !visitor or visitor.hashed != cookies[:visitor_md] then # 新規(未作成 or ハッシュとの不一致) Visitor.new elsif visitor.expired < Date.today + 30 then # 更新(30日以内に有効期限切れ) visitor else # 変更不要 nil end if new_visitor value = create_cookie_value new_visitor.value = value new_visitor.hashed = Digest::MD5.hexdigest(value+Time::now.strftime("%Y%m%d%H$M$s")) new_visitor.expired = 3.month.from_now new_visitor.must_send = true new_visitor.save new_visitor else visitor.must_send = false visitor end end private # クッキーの値を生成 def self.create_cookie_value() ActiveSupport::SecureRandom.hex(16) end end
controller
コントローラーでは、モデルのfind_from_cookieメソッドで得たcookieのモデルを取得、(必要であれば)クライアントへそのcookie値を送信するメソッドを定義。before_filterでそれを実行するようにしました。
class Customer::BaseController < ApplicationController before_filter :set_visitor_cookie attr_reader :visitor def initialize end protected # Visitorのcookie生成 # 未作成または、期限まで1ヶ月以内であれば新規cookieを生成 def set_visitor_cookie() visitor = Visitor.find_from_cookies(cookies) if visitor.must_send : cookies[:visitor] = {:value => visitor.value, :expires => visitor.expired } cookies[:visitor_md] = {:value => visitor.hashed, :expires => visitor.expired } end @visitor = visitor end end
ここで取得したcookieのモデル(visitorモデル)のidを他のテーブルから参照して、前回アクセス時の情報を復元するというような使いかたになるのかな?
次は?
このかたちじゃ、使いにくいので、Plugin化することを考えるかな?