スポンサーサイト
カテゴリ: スポンサー広告
[Rails]Hash#from_xml
カテゴリ: Rails
Rails使いがRailsをもっと好きになるHashメソッド集
from_xmlに感動したから紹介したいだけのお話
Hash.from_xml
RailsのHash拡張メソッド
XMLをHashにマッピングしてくれます
サンプルコード(rails cで実行します)
お天気Webサービス(Livedoor Weather Web Service / LWWS)のXMLをHashにマッピングします
require 'net/http'
response = Net::HTTP.start('weather.livedoor.com') do |http|
http.get('/forecast/webservice/rest/v1?city=113&day=tomorrow')
end
weather = Hash.from_xml(response.body)
weather['lwws']['location']
=> {"area"=>"九州", "pref"=>"福岡県", "city"=>"久留米"}
ちなみにActiveModel::Serializers::Xmlのfrom_xmlはこれを使っています
Hash#except, #extract, #slice
from_xmlと組み合わせると容易にXMLデータの解析ができてしまう
Hash.except
Hashから指定したキーを除外します
非破壊的メソッドのexcept, 破壊的メソッドのexcept!が存在します
data = {a: 1, b: 2, c: 3}
data.except(:a)
=> {:b => 2, :c => 3}Railsだと外部指定できないパラメータは
attr_protected :id, :created_at, :status_code等で保護する場面が多いですが、
外部指定をしたいけど、あるコントローラーからは外部指定できないようにしたい等の場合に以下のようにします
User.update_attributes(params[:user].except(:status_code)
これで外部からstatus_codeが送信されてきても保護することができます
Hash#extract!
必要な項目だけ抜き出すときに使います
こちらは実装の関係上破壊的なメソッドのみになります
x = { a: 1, b: 2, c: 3 }
=> {:a => 1, :b => 2, :c => 3}
x.extract!(:a, :b)
=> {:a => 1, :b=> 2}
p x
=> {:c => 3}破壊的メソッドのため、extract!した残りはそのフィールドが取り除かれたデータ(except実行後)になります
from_xmlと組み合わせて以下のように使ってます
data = Hash.from_xml(xml_data)["namespace"].extract!(:foo, :bar)
Hash#with_indifferent_access
シンボルでもストリングでもどっちでもアクセスできるようにします
x = { a: 1, b: 2, c: 3 }
x["a"]
=> nil
x.with_indifferent_access["a"]
=> 1
x.with_indifferent_access[:a]
=> 1これはまぁ"a".to_symしたのを渡してあげればいいんだけどね
File.atomic_write
Hash拡張の紹介のみの予定だったけど、Tempfileを使ってmvしている人を見かけたので、これも紹介
生成途中のデータを他のプロセス等に読み込まれたりしないようにするための仕組み
内部的にはTempfileを使っていて、Tempfileへの書き込みが完了した段階で、実ファイルを作成します
実装は以下の部分
https://github.com/rails/rails/blob/dd6c3676af3fa6019c53a59f62c4fd14966be728/activesupport/lib/active_support/core_ext/file/atomic.rb#L15
バッチ処理をRailsで書いているような場合はこれを使っておくと色々安全
File.atomic_write("my_batch_result.txt") do |file|
MyModel.find_each do |my_model|
file.puts my_model.to_a.join(",")
end
end




