Hatena::ブログ(Diary)

【旧】PerlerのRuby日記->はてなブログに移行しました

2013年11月12日

2013年11月11日

[]Sequelカラム名にはシンボルを使うこと

http://sequel.rubyforge.org/rdoc/files/README_rdoc.html

Column references in Sequel

Sequel expects column names to be specified using symbols.

はまったのでメモ。


条件に沿って"field1", "field2"のようなフィールドにアクセスするときに

間違ってもStringでSequelのwhereとかselectとかに渡してはいけない。


そのまま「文字列」として処理されてしまう。

mysql> select * from foo;
+------+------------+-----------------+
| id   | field1     | field2          |
+------+------------+-----------------+
|    1 | fooooo!!!! | FOOOOOOO!??!?!? |
+------+------------+-----------------+
1 row in set (0.00 sec)
$ sequel mysql2://user:password@localhost/hoge

2.0.0-p247 :001 > puts DB[:foo].select("field1").sql
SELECT 'field1' FROM `foo`
 => nil
# ↑field1はバッククオートではなくシングルクオート、つまり文字列!

2.0.0-p247 :002 > puts DB[:foo].select("field1").all
{:field1=>"field1"}
 => nil
# ↑得られる結果も当然そのまま!

2.0.0-p247 :003 > puts DB[:foo].select(:field1).sql
SELECT `field1` FROM `foo`
 => nil

2.0.0-p247 :004 > puts DB[:foo].select(:field1).all
{:field1=>"fooooo!!!!"}
 => nil
# ↑本当はこうしないといけなかった!

2.0.0-p247 :005 > num = 1
 => 1

2.0.0-p247 :006 > puts DB[:foo].select(:"field#{num}").sql
SELECT `field1` FROM `foo`
 => nil

2.0.0-p247 :007 > puts DB[:foo].select(:"field#{num}").all
{:field1=>"fooooo!!!!"}
 => nil
# ↑動的に作る場合ももちろんシンボルにすること!

2013年11月10日

[]Oj.dumpでシンボルを吐く時は:mode => compatする

Ojを知ったきっかけ

Padrinoでスケルトンを作るとGemfileにojというgemが入っている。

Optimized JSONの略らしい。


標準ライブラリとなったjsonよりも早いらしい。


Ruby - JSONの替わりに使ったOJが速い - Qiita


自分も、開発しているサービスで使われているJSONデータを使ってやってみたら、

確かにOjの方が早かった。

https://gist.github.com/rightgo09/6492700


Ojのdump mode

で、改めて触ってたら、デフォルトでOj.dumpでJSONを吐くと、

シンボルはすべて":hoge"のようになることが分かったのでメモ。


もしそれが意図しておらず、JavaScriptでコロンは不要なら、

:mode => :compat

が必要である。


Oj.dump({ :hoge => :fuga })
#=> {":hoge":":fuga"}

Oj.dump({ :hoge => :fuga }, :mode => :compat)
#=> {"hoge":"fuga"}

他のmodeは

  • :strict
    • JSONと同じ型だけをdumpできる
      • FalseClass, NilClass, TrueClass, Hash, Array, Numeric, String
    • これら以外のRubyの型が含まれているデータをdumpしようとするとTypeError Exceptionが投げられる
  • :null
    • :strict modeでExceptionが投げられるデータがnullになって、例外が投げられなくなる
  • :object
  • :compat
    • compatはcompatibilityの略
    • 渡されたObjectがto_hashかto_jsonを呼べればそれを使う。なければOjがよしなにしてくれる

また、default_optionsを最初に設定しておくこともできる。

Oj.default_options = {:mode => :compat}