LoginSignup
0

More than 3 years have passed since last update.

データを削除しようとしたらそのテーブルに主キーがなくて消せないんだけど

Posted at

冒頭

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つよつよの方へ

もしなにかしら方法をしっていたら教えてください🙇‍♂️
いや、普通に主キー作ればいいんだけどさ...

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0