やりたいこと
Rails 環境で、note 記事を rss で取得してDBに保存、自動表示させたい!✨
今回は、note 記事を取得するための rake タスクを作成します。
準備
- HTTP クライアントライブラリを
gemfile
に追加
本記事ではhttparty
を使用していますが、faraday
でも動作します。
参考: Awesome Ruby - Faraday VS httparty
- RSSフィード解析ライブラリ
feedjira
をgemfile
に追加
gem 'httparty'
gem 'feedjira'
$ bundle install
モデルの用意
今回は、特定のマガジンの記事の取得&タイトルと日付の表示が目的なので、シンプルに1つのモデルを作成します。
(複数のマガジンを取得するなら、もう1つモデルが必要そうです)
$ rails g model notice note_id:string title:string article_date:date
$ rails db:migrate
rakeタスク
タスクファイルを作成します📝
$ rails g task rss
Httparty.get
の後には取得したいページの"URL/rss"
を入れてください。
namespace :rss do
desc "note記事を更新"
task note_update: [:environment] do
xml = Httparty.get("https://note.com/○○/rss").body
rss = Feedjira.parse(xml)
rss.entries.each do |item|
id = item.url.split(File::SEPARATOR).last
date = item.published.strftime("%Y/%m/%d")
local_item = Notice.where(note_id: id).first_or_initialize
local_item.update!(title: item.title, article_date: date)
end
end
end
File::SEPARATOR
はファイルパスのセパレータです。
参考: constant File::SEPARATOR
rake rss:note_update
コマンドで、最新の25件(デフォルト値)の記事をDBに保存します。rails c
で保存されているか確認してみます。
pry(main)> Notice.count
=> 25
pry(main)> Notice.all
# ここに記事一覧がでます
first_or_initialize
でnote_id
がなければレコードを作成し、既にあれば更新するので、タイトルや記事が更新されても重複保存されません。
表示
記事のタイトルや内容を更新すると、表示順が一番後ろに変更されるので、article_date
の"DESC"
などで表示すると、間違いなく最新順に並ぶと思います。
<% articles = Notice.order(article_date: "DESC").take(8) %>
<% articles.each do |item| %>
<li><a href="https://note.com/○○/n/<%= item.note_id %>?magazine_key=○○">
<p><%= item.title %></p>
<span><%= item.article_date %></span></a>
</li>
<% end %>
その他
note_id
の一意性のテストなどを追加しました👍