全てのテーブルの全てのレコードの中から特定の単語を検索する方法
以下のコードをコピーして、検索したい文字列を入力して、コンソールで実行するだけで検索できます。
ActiveRecord::Base.connection.tables.each do |table|
model_name = "#{table.camelize.chop}".constantize rescue next
model_name.column_names.each do |column_name|
if model_name.columns_hash["#{column_name}"].type.to_s == ("string" || "text")
pp table_model.where("#{column_name} like ?", '%ここに検索したい文字を入力%') rescue next
end
end
end
よくわかる解説
大まかな方針としては、(モデル名).where("カラム名 like ?", "検索したい文字列")
を全てのモデルに対して実行します。
そのためには、全てのモデル名と全てのカラム名を取得する必要があります。
ActiveRecord::Base.connection.tables
で全てのテーブルの名前を抽出できます。ただし、この時点だとテーブル名がtable_namesのように複数形のスネークケースになっているのでモデル名にはなりません。そこで、
table.camelize.chop
で取得したテーブル名をキャメルケースに変換していきます。(テーブル名).camelize
でテーブル名が複数形のキャメルケースになります(例:TableNames)。また、chop
で単語の末尾の一字を削除できるのでTableNames
がTableName
のように変換されます。取得したモデル名はただのStringで、クラスではありません。そこで、
constantize
メソッドで文字列をクラスにしていきます。モデル名は取得できました。次はモデルにある全てのカラムを抽出していきます。カラムは
(モデル名).column_names
で取得可能です。テーブル名とカラム名は取得できたので、
(モデル名).where("カラム名 like ?", "検索したい文字列")
を実行すれば検索したい文字列は取得できます。ただし、booleanやintegerなどは検索対象外です。データ型がstringとtextの場合のみ検索を行います。モデルからカラム名を取得する方法は(モデル名).columns_hash["カラム名"].type
で取得できます。最後は定番のwhere~like?で検索すれば完了です!consoleで実行することが多いかと思います。ぜひご活用ください!