migrationファイル内では、モデルクラスを使わないのが安全です。
これは、将来的に仕様変更やリファクタでそのモデルがなくなったりリネームされた際、rake db:migrate:reset
が通らなくなるからです。
migration内でデータの変換処理をすることも多いので、SQLを生で叩くには以下のようにします。
sql = "UPDATE users SET some_flag = 1;"
ActiveRecord::Base.connection.execute(sql)
さすがにパラメータを指定したいことも多いですが、ActiveRecordのノリで?
などのplaceholderを渡しても処理してくれません。
かといって、自分でエスケープ処理をするのは嫌です。
このあたりのエスケープとプレースホルダー処理は、#sanitize_sql_array
が担当しています。
protectedメソッドですが、ここは使わせてもらっちゃいましょう。
args = ["UPDATE users SET name=? WHERE id=?", "Tom Brown", 1]
sql = ActiveRecord::Base.send(:sanitize_sql_array, args)
ActiveRecord::Base.connection.execute(sql)
なお、もう少し高級っぽく書くには、migrationファイル内でモデルクラスを定義してしまうという方法もあります。
追記(2019/03/07)
#sanitize_sql_array
はRails 5.2からpublicになりました🎉。
5.2からpublicやで https://t.co/lmuaeXnblI
— Ryuta Kamizono (@kamipo) August 8, 2018