Skip to content

Instantly share code, notes, and snippets.

@alpaca-tc
alpaca-tc / association_owner_validator.rb
Created May 23, 2021
関連の持ち主が同一人物であることをテスト
View association_owner_validator.rb
# 使い方
# validates_with(
# AssociationOwnerValidator,
# associations: {
# sub_item: :user
# },
# owner: -> { profile_image.user },
# if: %i[sub_item profile_image]
# )
class AssociationOwnerValidator < ActiveModel::Validator
@alpaca-tc
alpaca-tc / boolean_validator.rb
Created May 23, 2021
値がtrue/falseのいずれかであることをテスト
View boolean_validator.rb
# validates :column_name, boolean: true のように使う
class BooleanValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if value.is_a?(TrueClass) || value.is_a?(FalseClass)
record.errors.add(attribute, :not_boolean)
end
end
@alpaca-tc
alpaca-tc / ridgepole_unsigned_primary_id.rb
Created May 23, 2021
ridgepoleで全ての主キー・外部キーをunsigned: trueで定義する
View ridgepole_unsigned_primary_id.rb
# Schemafileで下記のように読み込む
# require_relative './lib/ridgepole_unsigned_primary_id'
# `create_table`, `t.references` で、常に `unsigned: true` を有効にするための拡張
# 個別に指定することもできるが、可読性が悪くなるのでデフォルトとする
module UnsingedReferences
def references(*args)
options = args.extract_options!
options[:unsigned] = true
args.push(options)
@alpaca-tc
alpaca-tc / ridgepole_hashed_index_name.rb
Created May 23, 2021
ridgepoleで定義するindex名をhashのランダム名で定義する(古いRailsっぽい挙動)
View ridgepole_hashed_index_name.rb
# Schemafileから
# require_relative './lib/ridgepole_hashed_index_name'
# して使う
module RidgepoleHashedIndexName
def index_name(table_name, options)
if options.is_a?(Hash) && options[:column]
identifier = super
hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
"index_rails_#{hashed_identifier}"
@alpaca-tc
alpaca-tc / active_record_dowsing.rb
Created May 23, 2021
クエリに発行元のコメントを含める処理の簡易版
View active_record_dowsing.rb
# frozen_string_literal: true
dowsing = Module.new do
def execute(sql, *)
source_location = query_source_location(caller.lazy)
sql = "#{sql} /* #{source_location} */" if source_location
super
end
private
@alpaca-tc
alpaca-tc / sidekiq_cron_spec.rb
Created May 23, 2021
sidekiq-cronのconfig/schedule.ymlがvalidであることをテスト
View sidekiq_cron_spec.rb
# frozen_string_literal: true
RSpec.describe 'sidekiq-cron' do
describe 'config/schedule.yml' do
let(:path) { Rails.root.join('config', 'schedule.yml') }
before do
Sidekiq::Cron::Job.load_from_array(YAML.load_file(path))
end
@alpaca-tc
alpaca-tc / factory_bot_spec.rb
Created May 23, 2021
FactoryBotの定義漏れ、不正な定義をテストする
View factory_bot_spec.rb
# frozen_string_literal: true
RSpec.describe FactoryBot do
shared_examples_for 'valid definition' do
it 'is valid' do
is_expected.to be_valid, (-> { factory.errors.full_messages.join("\n") })
end
end
FactoryBot.factories.map(&:name).each do |factory_name|
@alpaca-tc
alpaca-tc / missing_model_i18n_spec.rb
Created May 23, 2021
ActiveRecordのi18nの定義漏れをテストする
View missing_model_i18n_spec.rb
# frozen_string_literal: true
RSpec.describe 'ActiveRecord i18n' do
let(:table_names) { ActiveRecord::Base.connection.tables }
let(:models) do
table_names.map do |table_name|
table_to_model(table_name)
rescue NameError
nil
@alpaca-tc
alpaca-tc / db_seed_spec.rb
Created May 23, 2021
rake db:seed が例外を吐かないことをテストする
View db_seed_spec.rb
# frozen_string_literal: true
RSpec.describe 'rake db:seed' do
it 'works fine' do
expect { load('db/seeds.rb') }.to_not raise_error
end
end
@alpaca-tc
alpaca-tc / activerecord_duplicated_indexes_spec.rb
Created May 23, 2021
重複するインデックスを検知する
View activerecord_duplicated_indexes_spec.rb
# frozen_string_literal: true
RSpec.describe 'ActiveRecord duplicated indexes' do
let(:connection) do
ActiveRecord::Base.connection
end
it 'is not found' do
tables = connection.tables
duplicated_indexes = {}