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

# 結論

* Builder::XmlMarkupのほうが使いやすい
    * ただし、かなり古いgem（最終更新4年前）
* フラグメントキャッシュを合わせて使う


# 背景

RSS出力の実装方法として、主な方法としてRSS::MakerとBuilder::XmlMarkupの２つがあります。
私が担当していたサービスではMakerとBuilderが混在しており、どれがどう違うのかややこしかったという記憶があります。
ネットを調べてもどっちがどう違うかみたいなのが見当たらなかったので、まとめてみました。
で、実際どっちがいいのか、自分なりに結論も出してみました。

## RSS::Maker

RSS::Makerクラスを使って出力する方法です
[library rss (Ruby 2.4.0)](https://docs.ruby-lang.org/ja/latest/library/rss.html)

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

```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.](https://github.com/jimweirich/builder)
[Builder::XmlMarkup - APIdock](https://apidock.com/rails/Builder/XmlMarkup)
 
こっちは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を生成するのが良いと思いました。
なにかご意見、アドバイスがあればよろしくお願いします。