LoginSignup
123
117

More than 5 years have passed since last update.

Railsで定期実行したいスクリプトを書く

Posted at

Railsで定期実行したいスクリプトを書く

  • Ruby on Railsで定期的に実行したいスクリプトなどを書くときのメモです。
  • ハマりやすいところもある ので、全ての手順を記しておきます。

download.png

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に任せると楽チン

参考記事

123
117
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
123
117