Railsで定期実行したいスクリプトを書く
- Ruby on Railsで定期的に実行したいスクリプトなどを書くときのメモです。
- ハマりやすいところもある ので、全ての手順を記しておきます。
lib以下にスクリプトを記述
- twitterからタグのついたtweetを取得するスクリプトを取得する例
lib/sns/tw.rb
module Sns::Tw extend self
def batch
@client = config
tags = Settings.batch.hashtags
latest_tweet = Sns.where(sns_type_id: 2).order(post_date: :desc).first
latest_id = latest_tweet.nil? ? nil : latest_tweet.post_id
tags.each do | tag |
search(tag, latest_id)
end
end
private
def search(tag, latest_id)
# 最初であれば10件だけ取っておく
tweets = if latest_id.nil?
@client.search("##{tag}", locale: 'ja', exclude: 'retweets', result_type: 'recent', since_id: latest_id).collect.take(10)
else
@client.search("##{tag}", locale: 'ja', exclude: 'retweets', result_type: 'recent', since_id: latest_id).collect
end
tweets.each_with_index do | tweet, idx |
p idx
tweet.media.each do | media |
tw = Sns.find_or_create_by(sns_type_id: 2, post_id: tweet.id.to_s) do | sns |
sns.remote_image_url = media.media_url.to_s
sns.post_url = tweet.url.to_s
sns.post_date = tweet.created_at
end
end
end
end
def config
Twitter::REST::Client.new do |config|
config.consumer_key = ENV['TWITTER_CONSUMER_KEY']
config.consumer_secret = ENV['TWITTER_CONSUMER_SECRET']
end
end
end
autoload_pathsに追加
- この設定をしないと地味にハマります!!ご注意を!!!
config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
# 特にここ!!Rails5から productionでも呼び出せるように設定しないといけない
config.enable_dependency_loading = true
taskを作成
- コマンドでgenerateする
$ bundle exec rails g task sns
- rakeファイルを編集する
lib/task/sns.rake
namespace :sns do
desc "twitterのハッシュタグから画像を保存するタスク"
task twitter: :environment do
Sns::Tw.batch
end
end
- taskが動くか確認をする
# 一覧を表示
$ bundle exec rails -T
# 試しに実行する
$ bundle exec rails sns:twitter
定期実行する設定
- cronをいい感じに使えるgem
whenever
を使います。
gem 'whenever'
$ bunde install --path vendor/bundle
- 設定ファイルを作成
$ bundle exec wheneverize .
[add] writing `./config/schedule.rb'
[done] wheneverized!
- config/schedule.rb に設定を記述します。
config/schedule.rb
set :output, 'log/crontab.log'
ENV['RAILS_ENV'] ||= 'development'
set :environment, ENV['RAILS_ENV']
every 30.minutes do
rake "sns:twitter"
end
cronに反映する際のコマンド
- 設定の確認
$ bundle exec whenever
$ bundle exec crontab -e
- cronにデータを反映
$ bundle exec whenever --update-crontab
- cronからデータを削除
$ bundle exec whenever --clear-crontab
CapistranoでWhenever
- デプロイ時に、本番環境にもcronの値をセットしたい時は、Capistranoの設定ファイルに下記を追記します。
config/deploy.rb
set :whenever_command, "bundle exec whenever"
require "whenever/capistrano"
これで cap deploy を行なえば、デプロイ先のcrontabに値が反映されます。
まとめ
- lib/task に直接かきたくない
- lib以下にスクリプトを置かない派の人もいる
- crontabはwheneverに任せると楽チン
参考記事
- https://qiita.com/yumiyon/items/388fbb84450f49a6ab0d
- ありがとうございました!