コピペコードで快適生活

明日使えるソースを自分のために

RailsConsoleでSidekiqジョブの状況を見る

運用していると状況確認したいときがあるのでメモ。

## 実行中ジョブ
Sidekiq::Workers.new.each do |process_id, thread_id, job|
  puts "#{process_id}, #{thread_id}, #{job}"
end

## 待ち状態のジョブ
Sidekiq::Queue.new("#{QUEUE_NAME}").each do |job|
  puts "#{job}"
end

## 削除
Sidekiq::Queue.new("#{QUEUE_NAME}").clear


## リトライ待ちのジョブ
Sidekiq::RetrySet.new.each do |job|
  puts "#{job}"
end

## 削除
Sidekiq::RetrySet.new.clear

↑を踏まえてのワンライナーとか

## 実行中キュー確認
Sidekiq::Workers.new.each do |process_id, thread_id, job| puts "#{job['queue']}" end; 0

※参考にさせていただきました。
Sidekiqで実行中・待機状態・再試行のジョブを操作する - Qiita

ActiveRecordで固定の日時最小値チェックのバリデーションを入れる

#
# app/models/concerns/my_app/extend_validation.rb
# 複数のフィールドに対して一括でバリデーション設定できるようにするために
# バリデーションメソッドを追加するモジュール
#
module MyApp
  module ExtendValidation
    extend ActiveSupport::Concern

    module ClassMethods
      def validates_min_datetime_gteq(*args)
        options = args.extract_options!
        args.each do |key|
          validates key, min_datetime: (options.present? ? options : true)
        end
      end
    end
  end
end

# 
# app/validators/min_datetime_validator.rb
#
class MinDatetimeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    if value.present? && value < Time.zone.parse(Settings.validation.min_datetime)
      record.errors[attribute] << (
        options[:message] || I18n.t('errors.messages.on_or_after', {restriction: Settings.validation.min_datetime})
      )
    end
  end
end

参考にさせていただきました。
www.techscore.com

www.task-notes.com

cancancanでActiveRecord::RecordNotFoundを出したくないときのパッチ

module MyApp
  module CanCan
    module ControllerResourcePatch
      def find_resource
        # もともと定義してあるfind_resourceを呼び出す
        super
      rescue ActiveRecord::RecordNotFound => e
        # エラーさせたくないので握りつぶす
      end
    end
  end
end

CanCan::ControllerResource.prepend MyApp::CanCan::ControllerResourcePatch

書き換え元のメソッドはこちら。
https://github.com/CanCanCommunity/cancancan/blob/1.5.0/lib/cancan/controller_resource.rb#L98
たぶんバージョン違うときは、違うclassのメソッド書き換えが必要。

Rubyのinclude,extend,prepend,Concernの使い方メモ

なんとなく理解が怪しかったので復習をかねて。

includeだけでクラスメソッドとインスタンスメソッドを同時に追加する

module MyModule
  def self.included(base)
    base.extend(ClassMethods)
  end
 
  module ClassMethods
    def hogehoge
      puts 'hogehoge!'
    end
  end
 
  def fugafuga
    puts 'fugafuga'
  end
end

class TargetModel
  include MyModule

  # 略
end

・includeは、モジュールのメソッドをインスタンスメソッドとして追加する。
・extendは、レシーバ自身に対してメソッドを追加する。
 クラス.extend モジュール の場合はクラスメソッドとして
 インスタンス.extend モジュール の場合はインスタンスメソッドとして追加される。
・モジュールにincludedを定義しておくと、includeされたときに呼び出される。
 引数はincludeを行ったクラスやモジュール。

ActiveSupport::Concernを使う場合

require 'active_support/concern'
module ConsernModule
  extend ActiveSupport::Concern

  # インスタンスメソッドとして使える
  def hogehoge
    # do something
  end 

 # アクセサやscopeの定義はincludedの中で行う
  included do
    attr_accessor :fugafuga
    scope :favorites, -> { where(favirite_flag: true) }
  end

  # クラスメソッドの定義はclass_methodsの中で行う
  class_methods do
    def piyopiyo
      # do something
    end
  end

  # privateインスタンスメソッド
  private
  def wiblewible
    # do something
  end
end

class TargetModel
  include ConsernModule

  # 略
end

prependを使う

module TargetModelPatch
  def self.prepended(base)
    base.extend(ClassMethods)

    base.has_many :childrens
    base.scope :without_deleted, { where(deleted_at: nil) }
  end
 
  module ClassMethods
    def hogehoge
      puts 'hogehoge!'
    end
  end
 
  def fugafuga
    puts 'fugafuga'
  end
end

TargetModel.prepend TargetModelPatch

includeと基本的な動きは同じだけど、同じメソッドがあった場合はモジュール側のメソッドで上書きになる。

なお、includeの場合は取り込んだ側のメソッドが優先になる。
これは、includeすると見えないsuperclassとして継承階層の上(親クラス側)に挿入される?かららしい。


※参考にさせていただきました。
いつも忘れるRubyの include, prepend, extend の意味。そしてActiveSupport::Concernについても。
www.techscore.com

screenコマンドメモ

本番サーバで手動でバッチをまわしたけど、sshのセッションが切れて「あぁぁぁぁ」って、状況にしたくないときとかに使う。

セッションを作る

screen

デタッチする

<ctrl> + <a> おしてから d

セッション一覧

screen -ls

アタッチする

screen -r 
screen -r セッションID

screen内でスクロール

[CTRL]+[A] + [ESC] でモード切替して ↑↓で移動
もう一度、[ESC] 押すとモード戻る。

package.jsonで読み込み先を指定してインストール

たまにしか使わなくてよく忘れるのでメモ。

リポジトリ向ける

{
  "name": "app",
  "version": "0.0.1",
  "description": "app",
  "author": "kinosuke",
  "dependencies": {
    "common": "git+ssh://git@github.com:account/rep.git#branch"
  }
}

ローカル向ける

{
  "name": "app",
  "version": "0.0.1",
  "description": "app",
  "author": "kinosuke",
  "dependencies": {
    "common": "../rep"
  }
}