Rails + Semantic UIでmultiple select
Rails 5でsemantic-uiのmultipleなselectを使っているときに、初期値としてselectedされた値が表示されずに困っていた。 これはStackoverflowに書いてあった解決策だが、一旦option文のselectedを削除してからsemantic-uiのdropdown関数を呼び出しjavascriptからset selectedして、最後にoption文のseletctedを追加して元に戻しておく、というwalkaroundで解決した。以下に、coffeescript版を掲載しておく。
$(document).on 'ready turbolinks:load', -> $('.ui.dropdown').each -> $that = $(this) values = $that.val() $('option', $that).each -> $(this).removeAttr 'selected' return $that.dropdown 'set selected', values $('option', $that).each -> curr_value = $(this).val() i = 0 while i < values.length if values[i] == curr_value $(this).attr 'selected', 'selected' i++ return
で、これで解決と言いたいところだが、もう一工夫必要だった。selectedされてない場合はdropdown関数を呼ぶだけにすべき。
$(document).on 'ready turbolinks:load', -> $('.ui.dropdown').each -> $that = $(this) if $that.attr('multiple') && $('option[selected]', $that).length > 0 values = $that.val() $('option', $that).each -> $(this).removeAttr 'selected' $that.dropdown 'set selected', values $('option', $that).each -> curr_value = $(this).val() i = 0 while i < values.length if values[i] == curr_value $(this).attr 'selected', 'selected' i++ else $(this).dropdown()
参考 jquery - Semantic UI: Multi Select Dropdown pre-select values - Stack Overflow
ActionMailerとMS Exchange server
RailsのActionMailerをMS Exchange serverで使うには。
Gemfileに
gem "ruby-ntlm
config/environment.rbで
require 'ntlm/smtp'
config/environments/production.rbでメールサーバの設定
config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'mailserver.com', port: 25, domain: 'mail.com', user_name: 'username', password: 'password', authentication: :ntlm, enable_starttls_auto: false }
世界最長の吊り橋
7月にオープンしたスイスにある世界最長の吊り橋Europabrücke(ヨーロッパ橋)に行ってきたので、情報をまとめておく。まだ日本語情報はなかったし、英語でもニュース記事しかなたったので。行ったのは8月末。
場所
マッターホルンで有名なスイス南部の街、ツェルマットから電車で2駅15分程度のランダが最寄り駅。通常の観光であればツェルマットに宿泊して、ランダまで電車で移動するのが良いと思う。ランダは吊り橋以外には何もなさそうで、駅前に何もないし、無人駅だったとおもう。トイレはあった。切符はツェルマットからランダまでの往復を先に買っておいた方が良い。
ヨーロッパ橋まで
今回は次のサイトのコースを参考に吊り橋まで行って、ヨーロッパヒュッテには寄らずに戻った。
駅に降りたら山に向かって右に進んで行くが、あとは白の標識に従っていけばいい。橋ができたばかりなので、黄色の標識に追加して白の標識が後付けされている。自分はGPSで確認しながら進んだ。 ヨーロッパ橋までのアプローチは2つのセクションに分けられる前半2.3kmの激坂区間と、後半1kmの比較的歩きやすい区間。前半は駅からランダの街を抜けて登山道に入って行くが、ランダの街中からすでに激坂で、2.3kmで550m登る平均勾配なんと24%。とにかくコンスタントに登るので、休憩どころはない。心が折れそうになる。 少なくとも靴だけはちゃんとしたものは履いていかないとつらい。晴天でドライだったが、森林で直射日光はほとんどないので、快適。汗を発散する服装であればokと思う。 ランダ駅で降りたのは自分たちの他に3人1組だけだったけど、後から続々登って来て抜かれて行った。我々以外は欧米人で、もっと早いペースで登っているし、かなりラフな格好。おばちゃんでも日本人男性くらいのペースで歩くのでパワーが違う。
後半は勾配1%の快適なハイキングコース。特筆すべき点はない。
両親と一緒だったので休憩しながらゆっくりペース。前半区間を1.5時間、後半区間を40分で歩いた。60代女性でも完走したので、とんでもないコースではないが、誰にでも勧められる気軽な観光地ではない。少なくとも日本で山に行ったことがある人でないと、途中リタイアを余儀なくされるかも。 ここまで、全く吊り橋は見えず、突然目の前に現れるので感動はひとしお。
ヨーロッパ橋
500mあるので渡るのに10分くらいかかる。橋はギリギリすれ違えるくらいの幅しかないが、その方が両手で橋を持てるので安心。当日、風はほとんどなかったのもあるけど、思ったほど揺れない。それでもゆらゆらしてるので少し怖い。片側は山の斜面なので、空中を歩いてる感覚はなく、視覚的な恐怖はほとんどない。下はグレーチングなので下は見えるが、地面からの高さもそれほどない。中央から雪をかぶった山が左手に見えるのがハイライト。でもマッターホルンは全く見えません。 同時に渡っているのは大体10人以下だったし瞬間的には自分たちだけのこともあった。まだ、できたばかりだし、アプローチの難易度は高いし、まだまだ観光地化はしてない感じ。人が増えると景色は変わるだろう。 橋の両端に少し休憩できるスペースがあり、特に橋を渡ってからはテーブルや斜面など良い休憩場所があるので、サンドイッチでも持っていけば良い。橋の眺めも渡ってからの方がいい。20人くらいの人が常に休憩していた。TVクルーもいて何か撮影していた。 この橋はスポンサーからの資金提供で作られたようで、橋の手前に看板があるが控えめ。メインスポンサーのCharles Kuonenホテルの名前を冠して、Charles Kuonen Hängebrücke (Charles Kuonen suspension bridge)というのが正式名称みたい。
橋からの戻り
戻りは下り2.7kmで640m下るので平均24%の下り。岩も多く足場は悪いところが多い。気をつけないと足をくじいたりしかねない。1時間45分くらいで休憩しながら下った。たまたま電車が止まっていたのでツェルマット行きに飛び乗った。しっかり車掌が検札に来て、吊り橋に行って来たのか、と聞かれたので、地元でも注目スポット。 ランダの間にも小さな村だが、趣があって通り抜けるだけでもいい。まだ、観光の準備ができてない感じ。
その他
逆回りのコースはやめた方がいい。足場の悪いきつい登りを登るのはつらいし、何より登る前からチラチラ橋が見えてるので感動が薄い。逆回りしている人もいるけど多くはない。 登った満足感と、目前に突然現れる長い吊り橋、ゆっくり渡れる吊り橋、眺め、渡ってからの休憩スポット、など総じて満足感は高い。天気が良ければおすすめ。 観光地と呼ぶにはアプローチの難易度が高い。10年後にはロープウェイができてるかも。
最後に筆者は英語と少しのドイツ語がわかり、スイスには何度も行ったことがあって、ヨーロッパの電車移動も慣れているが、ハイキング初心者である前提と記載しておく。
ツール
GoPro Session バックパックの肩ストラップにGoPro Sessionをマウントして、2秒に1回のタイムラプスを取り続けた。SDカードは64GBで1日取れるが、バッテリーが全く持たないので、常にモバイルバッテリーから給電しながら記録した。記事の写真は全てGoProで撮ったもの。
iPhone + Geographica GPSがないと自分がどこにいるのかわからないので迷わないためにも必要。Google Mapsでもいいけど、標高みたいし、ログを取りたいのでGeographicaを購入した。
Swisscom prepaid SIM 1日2CHFでデータ通信が使い放題(4GB/月で減速のキャップあり)。LockされてないiPhone 6Sに入れて使った。
SBB Mobile アプリ スイスの電車の切符はアプリで買える。クレジットカード支払いできるので、電車移動するときは必須。検札に来たらチケットのバーコードを見せればOK。
MyGPSFiles 記録したGPXファイルは以下のサイトで可視化しみた。 MyGPSFiles
Redmine + view customize pluginで連続タスク入力を楽に
Futureパターン2
concurrent-rubyをつかうとfutureパターンが、かなりきれいに書ける。
require 'concurrent-edge'
Concurrent.future {
raise "exception" if [true, false].sample
true
}.then {|m|
puts "succeed #{m}" # 成功した時の処理、viewになげたり
}.rescue{|m|
puts "failed #{m}" # 失敗した時の処理
}.then{|m|
puts "finished" # finalize
}
sleep 0.1
SlimでHTMLメールを送る
HTMLメールをrubyで送るのにslimテンプレートエンジンを使いたくて。
require 'mail'
require 'slim'
mail = Mail.new do
from = 'foo@example.net'
to = 'bar@example.net'
subject = 'html mail'
end
@name1 = 'Sherlock Holmes'
@name2 = 'John Watson'
mail.html_part = Slim::Template.new('template.slim').render(self)
puts mail.to_s
template.slim
p =@name1 + ' is a private detective'
p =@name2 + ' is his assistant'
Futureパターン
EventMachineでFuture(Promise)パターンするときの例文をメモ
GitHub - cotag/em-promise: A promise/deferred implementation for EventMachine
require 'em-promise'
def testMethod
deferred = EM::Q.defer
EM.defer do
begin
# databaseなどを非同期処理
raise "exception" if [true, false].sample # テストなのでわざと例外発生
deferred.resolve('true') # 成功した時はresolveを実行、引数を渡せる
rescue => e
deferred.reject(e) # 例外のときはrejectを実行、引数を渡せる
end
end
deferred.promise # promiseを返す
end
EventMachine.run do
testMethod.then(proc{|m|
puts "succeed #{m}" # 成功した時の処理、viewになげたり
}, proc{|m|
puts "failed #{m}" # 失敗した時の処理
}).then(proc{|m|
puts "finished" # finalize
EM.stop
})
puts "async"
end
非同期実行なのでasyncが表示されてからtestMethodが、実行されます。 testMethodの中身を、もうすこしすっきり書きたいので、書き直し。
require 'em-promise'
def future
deferred = EM::Q.defer
EM.defer do
yield(deferred)
end
deferred.promise
end
def testMethod
future do |dfr|
begin
# databaseなどを非同期処理
raise "exception" if [true, false].sample # テストなのでわざと例外発生
dfr.resolve('true') # 成功した時はresolveを実行、引数を渡せる
rescue => e
dfr.reject(e) # 例外のときはrejectを実行
end
end
end
EventMachine.run do
testMethod.then(proc{|m|
puts "succeed #{m}" # 成功した時の処理、viewになげたり
}, proc{|m|
puts "failed #{m}" # 失敗した時の処理
}).then(proc{|m|
puts "finished" # finalize
EM.stop
})
puts "async"
end