結論
- Builder::XmlMarkupのほうが使いやすい
- ただし、かなり古いgem(最終更新4年前)
- フラグメントキャッシュを合わせて使う
背景
RSS出力の実装方法として、主な方法としてRSS::MakerとBuilder::XmlMarkupの2つがあります。
私が担当していたサービスではMakerとBuilderが混在しており、どれがどう違うのかややこしかったという記憶があります。
ネットを調べてもどっちがどう違うかみたいなのが見当たらなかったので、まとめてみました。
で、実際どっちがいいのか、自分なりに結論も出してみました。
RSS::Maker
RSS::Makerクラスを使って出力する方法です
library rss (Ruby 2.4.0)
コードは以下のようなイメージになると思います。
feed = RSS::Maker.make("2.0") do |feed|
feed.channel.title = "Sample"
feed.channel.link = "https://sample.jp"
feed.channel.about = "https://sample.jp/feed.xml"
feed.channel.description = "説明文"
feed.channel.updated = Time.zone.now
articles.each do |article|
feed.items.new_item do |item|
item.title = article.title
item.description = article.description
end
end
end
# save
File.open(Rails.root.join('public', 'feed.xm'), 'w') { |f| f.puts(feed) }
特徴
- RSSの種類ごとにフォーマットを自動でやってくれる
- 例:RSS2.0のlastBuildDateを自動でrfc822へ変換してくれる
- xmlns:contentなどを自動で設定してくれる
- そのため柔軟に書けないことがある
- 基本的に生成なのでpublic等に置く必要がある
- 動的に更新できない
- routesで管理できない
- gitignoreしないといけない
Builder::XmlMarkup
Builder::XmlMarkupクラスを使う方法です
jimweirich/builder: Provide a simple way to create XML markup and data structures.
Builder::XmlMarkup - APIdock
こっちはMakerと違ってviewファイルとして扱うことが出来ます。
ファイル名.xml.builderという名前で作成します。
xml.instruct! :xml, :version => 1.0
xml.rss(version: '2.0') do
xml.title "Sample"
xml.link "https://sample.jp"
xml.about "https://sample.jp/feed.xml"
xml.description "説明文"
xml.lastBuildDate Time.zone.now.to_s(:rfc822)
@articles.each do |article|
xml.item do
xml.title article.title
xml.description do
xml.cdata! article.description
end
end
end
end
特徴
- Makerより柔軟に記述できる
- ただしTimeのrfc自動変換などはやってくれない
- routesで管理できる
- 重い処理があった場合、アクセスするたびに負荷がかかる
このままでは負荷がかかってしまうので、以下のようにキャッシュを導入した方がいいです。
これで30分間キャッシュされるようになります。
cache 'feed_cache_key', expires_in: 30.minutes do
xml.instruct! :xml, :version => 1.0
xml.rss(version: '2.0') do
xml.title "Sample"
xml.link "https://sample.jp"
xml.about "https://sample.jp/feed.xml"
xml.description "説明文"
xml.lastBuildDate Time.zone.now.to_s(:rfc822)
articles.each do |article|
xml.item do
xml.title article.title
xml.description do
xml.cdata! article.description
end
end
end
end
end
余談
以下のようにしてRSS::Makerのように生成させることも可能です
feed = ''
xml = Builder::XmlMarkup.new(target: feed, indent: 4)
xml.instruct! :xml, :version => 1.0
xml.rss(version: '2.0') do
xml.title "Sample"
xml.link "https://sample.jp"
xml.about "https://sample.jp/feed.xml"
xml.description "説明文"
xml.lastBuildDate Time.zone.now.to_s(:rfc822)
articles.each do |article|
xml.item do
xml.title article.title
xml.description do
xml.cdata! article.description
end
end
end
end
結論
- 柔軟に記述できる
- routesで管理できる
という理由からRailsではBuilder::XmlMarkupクラスを使ってRSSを生成するのが良いと思いました。
なにかご意見、アドバイスがあればよろしくお願いします。