Edited at

RailsでRSSを生成する時に、MakerとBuilderどちらを使うべきか


結論


  • Builder::XmlMarkupのほうが使いやすい


    • ただし、かなり古いgem(最終更新4年前)



  • フラグメントキャッシュを合わせて使う


背景

RSS出力の実装方法として、主な方法としてRSS::MakerとBuilder::XmlMarkupの2つがあります。

私が担当していたサービスではMakerとBuilderが混在しており、どれがどう違うのかややこしかったという記憶があります。

ネットを調べてもどっちがどう違うかみたいなのが見当たらなかったので、まとめてみました。

で、実際どっちがいいのか、自分なりに結論も出してみました。


RSS::Maker

RSS::Makerクラスを使って出力する方法です

library rss (Ruby 2.4.0)

コードは以下のようなイメージになると思います。


feed.rake

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という名前で作成します。


app/views/rss/feed.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分間キャッシュされるようになります。


app/views/rss/feed.xml.builder

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.rake

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を生成するのが良いと思いました。

なにかご意見、アドバイスがあればよろしくお願いします。