RSS をパースするのに feed-normalizer を使っていたんだけど、Heroku 上で
require "open-uri" require "feed-normalizer" feedlink = "http://tnakamura.hatenablog.com/feed" feed = FeedNormalizer::FeedNormalizer.parse(open(feedlink)) feed.title #=> nil feed.url #=> nil
を実行したら title と url が nil を返してしまう。RSS をパースしたときはちゃんと取得できたんで、Atom をパースしたときこの問題に遭遇する模様。
ローカルでは取得できるのに、Heroku では取得できなくて嵌った。上記のサンプルを heroku run rails console で実行して発覚。対処方法は現在調査中だけど、ここまで調べるだけでも結構時間使ったんで、忘れないうちにメモっておこう。
追記1
feed.parser #=> "SimpleRSS"
を実行して、内部で使っているパーサーが SimpleRSS ということが分かった。SimpleRSS がちゃんとパースできていない可能性が高い。
追記2
SimpleRSS は parse の中で
tag_cleaned = clean_tag(tag) instance_variable_set("@#{ tag_cleaned }", clean_content(tag, $2, $3)) self.class.send(:attr_reader, tag_cleaned)
という風に、ATOM のタグと属性をもとに、動的にインスタンス変数とメソッドを作成していた。
そして、Heroku では
self.class.send(:attr_reader, tag_cleaned)
で動的に作成したアクセサが private メソッドになってしまっていた。試しに Heroku で
class Hoge; end h = Hoge.new("foo") h.instance_variable_set(:@age, 20) #=> 20 h.class.send(:attr_reader, "age") h.age #=> NoMethodError: private method `age' called for #<Hoge:0x0000000726ad70 @age=20>
を実行したら、動的に追加したアクセサが private メソッドになっているのを確認できた。ちなみに、ローカル環境で実行すると public メソッドになっていた。
title や author が private なメソッドなので、FeedNormalizer は title や author を取り出せない。その結果、nil が返していたようだ。
追記3
Feedzirra は Heroku でも動いたんで、RSS/Atom パーサーは次から Feedzirra を使おう。