jQuery Mobile 勝手に不正なページへ遷移してしまう時の対応

去年スマフォサイト作りました。

railsつかってます。
jQuery Mobileも使ってます。

mobileinitイベント内で

1
$.mobile.ajaxEnabled = false;

でAjaxオフにしてます。

でもたまにページロード完了後に、
勝手にローディング画像が出てきて、全然自分が見たいページとは違うページに飛ばされることがあります。

調べた結果Android端末の沢山とiPhone4以外(というか3GS?)で起きる現状でした。

上記現象が起こる操作は

Aページ- >[Bページへのリンクをクリック]- >Bページ- >[端末のブラウザバック]- >Aページ- >[Cページをクリック]- >Cページ読み込み完了後にBページに飛ばされる。

対策としては

1
$.mobile.pushStateEnabled = false;

でpushStateオフにしたら直りましたっていうお話。


Nヶ月前の月を求める

またまたRubyネタ。

Rails抜きでNヶ月前の月から今日までの月を求める必要があったので考えてみました。

すっごい遠回りして考えてるかもしれません。

rubyの配列はインデックスにマイナスを指定することができます。
その場合、参照する先は後ろから数えた値となります。

今日のコードはirbだけで試せます。
REPL最高。

1
2
3
a = [1,2,3]
a[0] # => 1
a[-1] # => 3

とりあえずNは3として、今月を含めて3ヶ月前を求めるには

1
2
month = [1,2,3,4,5,6,7,8,9,10,11,12]
month[Time.now.month-3]

1月ならば11月が帰ってきます。
2月ならば12月。3月なら1月となります。

インデックスは0始まりなのでそのあたりを考慮しないとあかんですね。

以上です。と書こうとしたけど、3ヶ月前から今日までの月でしたね。

1
3.times{ |i| p month[Time.now.month-i-1] }

先ほど述べたようにインデックスが0始まりなので-1してます。
配列で欲しいなら

1
3.times.map{ |i| p month[Time.now.month-i-1] }

かなぁ?


rubyはブロックを引数に取れる

わかりやすく書けるだろうか。

railsのviewでログの出力を出し分けする以下のメソッドがあります。

user profile log
use favorite log

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def genarate_link_path(log_type,log)
  case log_type
  when :warm
    "http://" + config[:host] + "/info/" + "warm"
  when :error
    "http://" + config[:host] + "/info/" + "error"
  end
end

def user_profile_log(log)
  disp_path = genarate_link_path(:warn,log)

  case log.operation_type
  when "insert"
    change_value = log.inspect + "ログを新規登録しました。"
  when "update"
    change_value = log.inspect + "ログを更新しました。"
  else
    "解析に失敗しました"
  end

  return link_to( change_value , disp_path )
end

def use_favorite_log(log)
  disp_path = genarate_link_path(:warn,log)

  case log.operation_type
  when "insert"
    change_value = log.name + "をお気に入りに追加しました。"
  when "update"
    change_value = log.name + "を更新しました。"
  else
    "解析に失敗しました"
  end

  return link_to( change_value , disp_path )
end

DRYじゃないですよね。
それぞれのメソッドでは
disp path = genarate link path(:warn,log)
return link
to( change value , disp path )
が二つのメソッドでかぶっております。

これをブロックで書き直します。

まずはブロックを引数に取るメソッド

1
2
3
4
5
def output(log,log_type,&block)
  disp_path = genarate_link_path(log_type,log)
  change_value = block_given? ? block.call : "ブロックもらえてないんで表示できません"
  link_to( change_value , disp_path )
end

&blockでブロックを引数に取れます。
受け取ったブロックはblock.callで実行できます。
ブロックがもらえたかどうかはblock _given?で判定できます。

んでブロックを引数にouput呼び出す方も修正。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def user_profile_log(log)

  output(log,:warm) do
    case log.operation_type
    when "insert"
      change_value = log.inspect + "ログを新規登録しました。"
    when "update"
      change_value = log.inspect + "ログを更新しました。"
    else
      "解析に失敗しました"
    end
  end

end

def use_favorite_log(log)

  output(log,:error) do
    case log.operation_type
    when "insert"
      change_value = log.name + "をお気に入りに追加しました。"
    when "update"
      change_value = log.name + "を更新しました。"
    else
      "解析に失敗しました"
    end
  end
end

っていう。

説明できたか以前にソース汚いという。
あと思ったより再利用性の高いコードが書けなかったという。

ちなみに&blockしなくてもブロックは受け取れてその場合は

1
2
3
4
5
def output(log,log_type)
  disp_path = genarate_link_path(log_type,log)
  change_value = yield
  link_to( change_value , disp_path )
end

となります。
ブロックが渡されることが確実に保証されているならばこっちの方がいいのかな