[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"}]