4

私は、親が乳児の睡眠を追跡するのに役立つRailsアプリを作成しました。それが正しく機能するためには、さまざまなタイムゾーンをサポートする必要がありました。タイムゾーンでユーザーを煩わせることを避けるために、タイムゾーンオフセットを含む非表示フィールドをログインフォームに追加する小さなJavaScriptを作成しました。これがコードです

var timeZoneField = $("input[name='user_tz_offset']");
  if (timeZoneField.length) {
    var browserDate = new Date();
    var timeZoneOffsetSeconds = (browserDate.getTimezoneOffset() * 60) * -1;
    $(timeZoneField).val(timeZoneOffsetSeconds);
  }

そのフィールドのデータを使用して、Time.zoneをそのオフセットに対応する都市に設定しました。このようなものがタイムゾーンを生成します

user_time_zone = ActiveSupport::TimeZone.[](params[:user_tz_offset].to_i)
session[:user_time_zone] = user_time_zone

最後に、ApplicationControllerでタイムゾーンを設定します。

def set_user_time_zone
  if (session[:user_id])
      Time.zone = session[:user_time_zone]
  else
    Time.zone = config.time_zone
  end
end

これはすべて、私が自分で書いたログイン機能に依存しています。ただし、自分のコードは十分に機能しておらず、特に安全でもないため、後でより優れたユーザー管理システムを使用する必要があることはわかっていました(最初は他の機能に焦点を合わせていました)。

今、私はdeviseをインストールしました、そしてそれはログインとログアウトにうまく機能します、サイトの他のほとんどの機能も同様に機能します。しかし、ユーザー管理システムとしてdeviseを使用してタイムゾーンサポートにアプローチする方法がわかりません。

1つのアイデアは、DeviseのSessionsControllerをオーバーライドし、その非表示のタイムゾーンフィールドのチェックを追加して、その値をuser_sessionに追加することです。しかし、そうすることには不安を感じます。それは悪い考えのように感じます。

登録時にユーザーにタイムゾーン情報を追加させることなく、この機能を追加するためのより良い方法はありますか?

ありがとうございました!

4

2 に答える 2

2

スケジューリングソフトウェアを管理しており、ブラウザのタイムゾーンも確認していますが、データベースに保存して、アプリケーションコントローラのbefore_filterを使用して呼び出しています。

#Application Controller
before_filter :set_time_zone

private

def set_time_zone
  if current_user
    Time.zone = current_user.time_zone if current_user.time_zone
  end
end
于 2012-11-13T17:01:11.460 に答える
2

約8時間の試行錯誤の末、今のところうまくいく解決策を思いつきました。おそらく、これは同様の設定を持つ人にとって興味深いかもしれません。

モデルのusersテーブルと対応する属性に列を追加することから始めました– session_tz_offset

それから私はWardenコールバックでハッキングを始めました。私にとってうまくいったのは、ApplicationControllerにヘルパーメソッドを配置し、次のようなbeforeフィルターを使用してそれを呼び出すことでした。

before_filter :authenticate_user!, :set_session_tz_offset_for_user

helper_method :set_user_time_zone, :set_session_tz_offset_for_user

def set_session_tz_offset_for_user
  Warden::Manager.after_authentication do |user, auth, opts|
    if (params[:user])
      user.session_tz_offset = params[:user][:session_tz_offset]
      user.save
    end
  end
end

after_authenticationコールバックは、ログイン中に数回発生します。理由はわかりません。これらの呼び出しのすべてにparams[:user]フィールドがあるわけではなく、それをチェックしなかった場合、アプリケーションがundefined method [] for nil:NilClassエラーでクラッシュしました。

session_tz_offset設定されると、他のコントローラーは、ApplicationControllerで定義されている別のヘルパーメソッドを使用しTime.zoneて、現在のリクエストを設定します。

  def set_user_time_zone
    if (user_signed_in?)
      if(user_session[:time_zone])
        Time.zone = user_session[:time_zone]
      else
        user_session[:time_zone] = 
            ActiveSupport::TimeZone.[](current_user.session_tz_offset)
        Time.zone = user_session[:time_zone]
      end
    else
      Time.zone = config.time_zone
    end
  end
于 2012-11-15T12:14:19.740 に答える