LoginSignup
2
2

More than 3 years have passed since last update.

【Rails】note記事をrssで取得するrakeタスクを作る

Last updated at Posted at 2020-11-07

やりたいこと

Rails 環境で、note 記事を rss で取得してDBに保存、自動表示させたい!✨
今回は、note 記事を取得するための rake タスクを作成します。

準備

  • HTTP クライアントライブラリをgemfileに追加

本記事ではhttpartyを使用していますが、faradayでも動作します。

参考: Awesome Ruby - Faraday VS httparty

  • RSSフィード解析ライブラリfeedjiragemfileに追加
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"を入れてください。

lib/tasks/rss.rake
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_initializenote_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の一意性のテストなどを追加しました👍

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2