コピペコードで快適生活

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

Rails

db:migrateで巨大なテーブルへadd_column+default値設定をする

Rails + PostgreSQL環境での話。 数千万行あるような巨大なテーブルに対して、add_column+default設定をまとめて設定すると、サービスを止めてしまうほどに長時間テーブルロックかかってしまう。AccessExclusiveLockなのでSELECTも通らない。 原因は、ALTER_…

Grape+Rspec環境でAPIをテストする

既存RailsアプリにRspecを入れる - コピペコードで快適生活 の続き。まず、JSONのテストを簡単にするgemを入れる。 gem 'json_expressions' テストコードはこんな感じで書ける。 require 'rails_helper' require 'json_expressions/rspec' describe "GET api…

PostgreSQLでプロセスとロック状況を確認する

## 実行中のSQLを確認する。 SELECT * FROM pg_stat_activity; ## 実行中のSQLを確認する ## スロークエリとか主に見る分だけ SELECT pid, query_start, substr(query, 0, 80) AS query FROM pg_stat_activity WHERE state='active' ORDER BY query_start; #…

RspecでSQLやRailsのログを出力したい

こんな感じで # spec/rails_helper.rb # 略 Rails.logger = Logger.new(STDOUT) # Rails.loggerを出す ActiveRecord::Base.logger = Logger.new(STDOUT) # SQLログ出す RSpec.configure do |config| # 略 end ※STDOUTは組み込み変数 STDOUT.puts "hogehoge" …

ActiveRecord::Base.transactionで並列で同じレコードを扱ったときの動きメモ

排他制御まわりがちゃんとわかっていなかったので整理。 Article.find(1).value # => 1 def inc row = Article.find(1) row.value = row.value + 1 row.save end # 同時並行処理する Thread.new { inc } Thread.new { inc } Article.find(1).value # => 2に…

ActiveSupport::CallbacksでRubyクラスにコールバックを差し込む

ActiveRecordじゃなくてもコールバックは使えるんやで。 class Article include ActiveSupport::Callbacks define_callbacks :before_submit set_callback :before_submit, :before, :validation def validation puts 'Check!!!' end def submit puts 'Submi…

ActiveRecordのafter_commitが発火するとき発火しないとき

発火する ・なにも変更せずにsaveしても発火する(select文しかないtransactionでcommitがされるため) ・destroyで発火する。self.destroyed?はtrue, self.reloadでActiveRecord::RecordNotFound ・soft_destroyでも発火する。self.soft_destroyed?はtrue (ka…

class_evalを使って、classに自由な名前でメソッドを追加

concernに書くとこんな感じか。 # # include ::Logica::DateRangeSearchable # date_range_name_is :validity, :valid # # klass.valid # -> validity_start_at, validity_end_atが期間内のみ取り出す # instance.valid? # -> validity_start_at, validity_e…

Rubyでたまにしか使わないけど便利なメソッドメモ

備忘のため。随時追加していく。 Ruby # フィールドをもつモックオブジェクトを作る Struct.new(:name, :tel).new('hogeo', '090xxxxxxxx') # => #<struct name="hogeo", tel="090xxxxxxxx"> # irbでeach回して処理した後、そのリストを出力させたくない list.each do |row| # 何かしらの処理 end; 0 </struct>…

既存RailsアプリにRspecを入れる

既存RailsアプリにRspecを入れたときのメモ。 インストール Gemfileに追記 group :development, :test do gem 'rspec-rails' gem 'factory_bot_rails' gem 'database_cleaner' end RSpecの設定 必要なファイルが作成される。 bundle install bundle exec rai…

sidekiq-unique-jobsのunique値ごとの挙動

ちょっと古いけど、sidekiq-unique-jobs v4.0.8のunique値ごとの挙動を確認したのでメモしておく。GitHub - mhenrixon/sidekiq-unique-jobs at v4.0.8 while_executing 同じargsは実行中にならない。 同じargsを実行しようとしたらworkerは待ちになる。後続…

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|…

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

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

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

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

ffiのインストールで失敗する時

こんなエラー An error occurred while installing ffi (1.9.21), and Bundler cannot continue. Make sure that `gem install ffi -v '1.9.21'` succeeds before bundling.ライブラリがないっぽいので sudo yum install ruby-devel libffi-develすればOKだ…

CarrierWaveで既にアップロード済のファイルに新しいバージョンをあてる

User.all.each do |user| if user.avatar_file.present? user.avatar_file.recreate_versions! user.save end end

Rubyで名詞の単数形・複数形を変換する

たまにやりたくなる。いつもメソッド名忘れているけど。 require 'active_support' 'user'.pluralize # => users 'users'.singularize # => user

RailsConsoleでサクッとメール送信

本番環境でメール送信チェックとかするとき用に。 ActionMailer::Base.mail(to: "test@example.com", from: "test@example.com", subject: "題名", body: "本文").deliver

RailsのArelの使い方

RailsでArelを使うときは、下記サイトをいつも参照させていただいていましたが、自分メモ用として転載します。 メモ || Arelのwhere系メソッド一覧 User.w... User.where(User.arel_table[:name].eq("aa")).to_sql # => SELECT "users".* FROM "users" WHERE…

Rails×SES バウンスメール(不達メール)対策

「SESで不達メールが多いから、対策してくれなかったらSES止めるよ」って過去にAWSから言われたことがあって、そのときの対応メモを書きだしてみた。対応の基本的な流れ SESは不達メールがあった場合に特定のURLに対してリクエストをjson付きで投げてくれる…