Railsでスケジュール投稿(1日単位)機能を作成する方法

✏️️ 2019/09/08 👍️2019/09/13 🔗

Rails アプリケーションにスケジュール投稿機能を作成します。

published_at カラムを追加

bin/rails g migration add_published_at_to_post published_at:datetime
# マイグレーションファイル
class AddPublishedAtToPost < ActiveRecord::Migration[6.0]
  def change
    add_column :posts, :published_at, :datetime
  end
end 
bin/rails db:migrate

フォームにpublished_at欄を追加します

  <div class="field published-field">
    <%= form.label :published_at, class: 'label' %>
    <div class="control">
      <%= form.datetime_select :published_at %>
    </div>
  </div>

ストロングパラメーターにpublished_atを追加

# app/controllers/admin/posts_controller.rb
def post_params
  params.require(:post).permit(:title, :content, :slug, :status, :category_id, :published_at, tag_ids: [])
end

Model

enumにscheduledを追加します。

# app/models/post.rb
enum status: { draft: 0, published: 1, scheduled: 2, archived: 10 }

また、Validation時にpublished_atカラムをチェックするロジックを作成します。

before_validation :clean_up_status

  def clean_up_status
    self.published_at = case status
                        when 'draft'
                          nil
                        when 'scheduled'
                          Time.zone.now
                        else
                          published_at
                        end
    true
  end

statusが draft のときはpublished_atカラムをnilにします。scheduledのときは現在時刻。他の場合は変更しません。

Rakeタスクを作成

最後にRakeタスクを作成します。publishd_atが本日のものを全てpublishedに変更してます。

# lib/tasks/schedule_post.rake
namespace :posts do
  desc 'Update scheduled post status'
  task update_scheduled_post: :environment do
    time = Time.zone.now
    posts = Post.scheduled.where(published_at: (time.beginning_of_day..time.end_of_day))
    posts.update_all(status: 'published')
  rescue StandardError => e
    Rails.logger.error e.message
  end
end

クーロンに登録

今回は一日単位でクーロンを回してます。もっと細かい単位でスケジュール投稿したいならば、lib/tasks/schedule_post.rakeの間隔を短くして、クーロンを細かくすればOKです。

# config/schedule.rb

every 1.day, at: '5:00 am' do
  rake 'posts:update_scheduled_post'
end

以上で、Railsでスケジュール投稿(1日単位)機能を作成する方法は完了です。

akito
日本のスタートアップで主にRuby on Railsを使ってプロダクト開発をしています。