冒頭
LaravelからRailsに改修をする案件をしていたときのことで、
既存のDBがあるためそれをself.table_name
で指定してあげて使えるようにしているのですが、
データを論理削除する際に以下の問題にぶち当たりました。
問題のエラー
ActiveRecord::StatementInvalid (Mysql2::Error: Unknown column 'テーブル名.' in 'where clause')
え、なんでカラムがないの?
と思いSQLを出力させたところ、
UPDATE `テーブル名`
SET `テーブル名`.`deleted_at` = '2019-10-11 18:12:27'
, `テーブル名`.`updated_at` = '2019-10-11 18:12:27'
WHERE `テーブル名`.`` IS NULL
といった状態に。
DB設計書を確認したところ、どうやら主キー(Primary Key)がこのテーブルないとさ。
なるほど、そりゃ主キーないんだからカラムが空なわけ。
調査
where句を別のものに指定できないものかと調べたらRails6から実装されているこんなものを見つけました。
# Finds and destroys all records matching the specified conditions.
# This is short-hand for <tt>relation.where(condition).destroy_all</tt>.
# Returns the collection of objects that were destroyed.
#
# If no record is found, returns empty array.
#
# Person.destroy_by(id: 13)
# Person.destroy_by(name: 'Spartacus', rating: 4)
# Person.destroy_by("published_at < ?", 2.weeks.ago)
def destroy_by(*args)
where(*args).destroy_all
end
だけどこれ結局のところdelete_all
使ってるんで意味ないやん。
あ" き" ら" め" た"
対応
生SQLをつかうことにした。
sql = <<-SQL
UPDATE `テーブル名`
SET `テーブル名`.`deleted_at` = '#{Time.current}'
, `テーブル名`.`updated_at` = '#{Time.current}'
WHERE `テーブル名`.`カラム名` = 'XXX'
SQL
con = ActiveRecord::Base.connection
con.execute(sql)
Railsつよつよの方へ
もしなにかしら方法をしっていたら教えてください🙇♂️
いや、普通に主キー作ればいいんだけどさ...