ActiveRecord使ってMySQLの日付関数呼び出す時の注意
AWS+RDSでRailsを使ったりしてると、RDSのタイムゾーンがUTCから変更できない関係で、けっこう時間の扱いに悩みます。
大抵の場合、application.rbに
とかやってお茶を濁すわけですが。config.time_zone = 'Tokyo'
config.time_zoneはあくまでアプリケーション側の時間の扱いなので、DBのタイムゾーンを帰るわけではありません。
なので、date関数とか使うとUTC扱いになって困っちゃったりするわけです。
そういう場合はCONVERT_TZで無理くりJSTにします。
User.where("DATE(CONVERT_TZ(regist_day,\"+00:00\",\"+09:00\"))
MySQL5.6のSQLモード
ついに出ましたね、MySQL5.6!
my.cnfの位置が/usr/my.cnfに変わったとか標準動作がinnodb_per_tableになったとか色々ありますが、とりあえずデフォルトのmy.cnf内に
という記述があって、詳細はこちらを見ていただくとして、今まではsql_mode=TRADITIONALだったのですが、このまま起動するとSTRICT_TRANS_TABLESモードで起動してしまいます。sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
TRADITIONALはカラムレングスよりも長い文字列のレコードがインサートされた場合、カラムに入らない部分を切り捨てて格納し、エラーメッセージを返すんですが、STRICT_TRANS_TABLESだとインサートエラーを返します。
WEBアプリでレングスチェックをしているのでMySQL側でチェックする必要ないよ、という人はTRADITIONALモードに変更しましょう。
TRADITIONALモードで起動した場合、余計チェックが厳しくなりました><
5.6はTRADITIONALモードも変更が入ってるらしい。。。
mysql> select @@global.sql_mode;
- ------------------------------------------------------------------------------------------------------------------------------------------------------+
@@global.sql_mode
- ------------------------------------------------------------------------------------------------------------------------------------------------------+
STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
- ------------------------------------------------------------------------------------------------------------------------------------------------------+
nginxでDOCOMOのguidを取得する
ガラケーのサービスでnginxをあまり使わないからなのか情報が見つからなかったのでメモ
nginx.confで
HTTP_X_DCMGUIDはアンダースコアを含むのでunderscores_in_headersをONしないと取れませんでした。# アンダースコアを有効に
underscores_in_headers on;
# ログフォーマットに追記
log_format custom '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time "$http_x_dcmguid"';
Backbone.jsで外部ファイルをテンプレートに指定する方法
このエントリはBackbone.js Advent Calendar11日目です。
皆様素晴らしいエントリを書かれている中、何か初歩的なエントリでスミマセン。
Backbone.jsで作られたサイトを見ると、よく_.templateを使ってHTMLを呼び出す記述を見かけますね。
よく知られているように、_.templateには文字列を渡す方法とtext/templateセクションをセレクタで渡す方法があります。
文字列で渡す
_.template('<div><%= name %></div>',name)
テンプレートセクションをセレクタで指定する
_.template($('#item-template').html(),name)
テンプレートセクションの記述はunderscore.jsの呼び出し元HTMLである必要があります。item-templateのテンプレートセクション
<script type="text/template" id="item-template">
<div class="view">
<input class="edit" type="text" value="<%= name %>" />
</div>
</script>
ところでサーバサイドのMVCフレームワークに慣れ親しんだ人はこれがちょっと違和感で、できればテンプレートを分離して別ファイルにしてviewsフォルダとかにまとめたい欲望に駆れたことはないでしょうか。
しかしながら御存知の通りクライアントサイドJavascriptは表示しているHTMLのDOMに対する操作を主に行うためのもので、別ディレクトリの要素については全く関与しません(当たり前)。
でもデザイナーと分業したり、テンプレートセクションが増えすぎてソースが汚くなるのは嫌だから分離させたら何かと便利じゃない?、という人のために、viewsフォルダを分けて管理する方法について、敢えて考えてみたいと思います。
まずテンプレートを格納するためのフォルダを作成します。フォルダはAJAXでJSからアクセスできる必要があり、今回は/viewsとします。
次に指定されたファイル名でviewsフォルダからHTMLを取得する関数を作成します。名前は何でもいいので今回は_renderという名前にしました。index.htmlはbackbone.js, underscore.jsの呼び出し元
index.html
views/ここにテンプレートファイルを入れる
2度めからのアクセスはキャッシュから参照させるため、tmpl_cacheというキャッシュ格納用変数も用意します。
_renderは拡張子を省略したファイル名を渡すと、viewsディレクトリからHTMLを取得して文字列を返す関数です。var tmpl_cache;
function _render(tmpl_name) {
if ( !tmpl_cache ) {
tmpl_cache = {};
}
if ( ! tmpl_cache[tmpl_name] ) {
var tmpl_url = 'views/' + tmpl_name + '.html';
var tmpl_string;
$.ajax({
url: tmpl_url,
method: 'GET',
async: false,
dataType: "html",
success: function(data) {
tmpl_string = data;
}
});
tmpl_cache[tmpl_name] = tmpl_string;
}
return tmpl_cache[tmpl_name];
}
一度呼び出したテンプレートはキャッシュ変数に保持して二回目のアクセスはAJAX通信が発生しないようにします。またacyncをfalseにして強制的に同期処理させます。
View側からは_.templateの第一引数に_renderを指定します。
viewsにitem-template.htmlを作成します。_.template(_render("item-template"),name)
_renderがAJAX通信して取得した結果を、HTMLとして_.templateに渡す感じになります。これで別ディレクトリに作成したテンプレートを_.templateに渡すことができるようになりました。views/item-template.html
<div class="view">
<input class="edit" type="text" value="<%= name %>" />
</div>
しかしながらこの方法、テンプレート取得のたびに無駄なAJAX通信が発生するため、WEBサイトでやる意味はほとんどないと思います。
ですのでPhoneGap+Backbone.jsでアプリを作る時などローカル限定での呼び出しに留めておくのが良いと思います。
というわけで、Backbone.jsほとんど関係ないエントリになってしまいましたが、以上よろしくお願い致します。
therubyracerでインストールエラー
Railsでプロジェクト作ろうと思ったらなぜかbundle installでエラーが発生する。
/usr/local/rvm/rubies/ruby-1.9.3-p194/bin/ruby extconf.rb
checking for main() in -lpthread... yes
checking for v8.h... no
therubyracerインストール中にlibv8が見つからずエラーになってるみたい。
とりあえずlibv8を入れなおす。
gem uninstall libv8
gem install libv8
単体でtherubyracerをインストールする
gem install therubyracer
なぜかsyntax errorで怒られる。linking shared-object v8/init.so
/usr/bin/ld:/usr/local/rvm/gems/ruby-1.9.3-p194/gems/libv8-3.11.8.3-x86_64-linux/vendor/v8/out/x64.release/obj.target/tools/gyp/libv8_base.a: file format not recognized; treating as linker script
/usr/bin/ld:/usr/local/rvm/gems/ruby-1.9.3-p194/gems/libv8-3.11.8.3-x86_64-linux/vendor/v8/out/x64.release/obj.target/tools/gyp/libv8_base.a:1: syntax error
この間までは動いていたので、どうやらtherubyracerのバージョンが上がったのが原因くさい。
rubygems.orgで確認。
日付的に0.11.0のGAと相性が悪いっぽいので、beta8を指定してbundle install
all versions of therubyracer101 versions since December 21, 2009
0.11.0 December 4, 2012
0.11.0beta8 August 13, 2012 x86_64-linux
gem 'therubyracer', '0.11.0beta8'
うまくいった!Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.