« [Trac][SVN] Trac+SVNな環境構築。 | メイン | [Ruby][Rails] HTTPレスポンスのヘッダ折りたたみ。 »

[Rails] SymbolとStringで悩む。

こんにちわ。ばたっちです。

Rails って Symbol と String(文字列)の区別がなく使えるのかと思いきや、ActiveRecordのオブジェクトなどで record[:name]でも record["name"]でも参照できるのは、ActiveRecordクラスでラップしてるからのようで。

Symbolで参照できたり、文字列じゃないといけなかったり変だなーと思ってたら、ActiveRecordで SQLによる検索に connection.select_all(sql)を使ってたからでした。。orz

Rails は全体的に Symbolで統一しようとしている雰囲気なので、ここはなるべく Symbolで参照したいところ。

select_all(sql)の結果は単なるハッシュの配列ですが、find_by_sql(sql)を使うとActiveRecordオブジェクトの配列になります。


class Name < ActiveRecord::Base
end

※connection.select_all の結果はハッシュの配列。
Name.connection.select_all("SELECT * FROM names LIMIT 1")
=> [{"name"=>"名前1", "created_at"=>"2007-12-19 12:00:00"}]

※find_by_sql の結果はActiveRecordの配列。
Name.find_by_sql("SELECT * FROM search_logs LIMIT 1")
=> [#<Name:0x99999999 @attributes={"name"=>"名前1", "created_at"=>"2007-12-19 12:00:00"}>]

※find_by_sql で任意の結果も取れる。@errorsがあるけど参照は問題なさそう。
Name.find_by_sql("SELECT name, substring(created_at, 1, 10) day FROM names LIMIT 1")
=> [#<Name:0x99999999 @attributes={"day"=>"2007-12-19", "name"=>"名前1"},
           @errors=#<ActiveRecord::Errors:0x99999999 @base=#<Name:0x99999999 ...>, @errors={}>>]

※find の結果はActiveRecord。
Name.find(:first)
=> #<Name:0x99999999 @attributes={"name"=>"名前1", "created_at"=>"2007-12-19 12:00:00"}>

find_by_sqlで任意のカラムの結果が取れるとは知らなかった。

@errorsがあるけど、ちゃんと参照はできます。


result[:name]
=> "名前1"

result["name"]
=> "名前1"

@errorsが気持ち悪かったら connection.select_all の結果ハッシュのキーをSymbol変換するかなぁ。


def to_symhash(hash)
 result = {}
 hash.each_key {|k| result[k.to_sym] = hash[k] }
 result
end

results = Name.connection.select_all("SELECT * FROM names LIMIT 1")
results.collect{|r| to_symhash(r) }
=>[{:created_at=>"2007-12-19 12:00:00", :name=>"名前1"}]

トラックバック

このエントリーのトラックバックURL:
http://pw.tech-arts.co.jp/cgi-bin/tamt32/mt-tb.cgi/62

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)