[Rails6]devise+paranoia+MySQL8계에서 실현되는 유저 논리 삭제와 일의 제약의 양립

소개



타이틀 환경에서 사용자의 논리 삭제와 고유 제약의 양립에 상당히 고전했기 때문에
해결 방법을 가볍게 정리합니다.
devise의 일의 제약을 오버라이드(override) 해 독자적인 제약을 갖게 하는 방법등이 나왔습니다만
아무도 귀찮고 더 쉽게 할 수 없을까 생각해 조사한 결과입니다.

하고 싶은 일



이전 환경에서 (특히 MySQL) devise 기본 사용자 물리적 삭제 대신 논리 삭제를 수행하고
또한 탈퇴한 유저가 같은 주소나 ID로 재등록할 수 있도록 일의 제약을 담보하고 싶다.

PostgreSQL, SQLite



이쪽 2개의 DB에서는 부분 index를 활용하는 것으로 간단하게 구현할 수 있다고 합니다.
・실장 기사
· add_index 사양 1
· add_index 사양 2

이, 부분 index를 MySQL은 채용하고 있지 않고 간단하게 취급할 수 없는 모양.
(정보가 5.7뿐이기 때문에 8계에서는 채용하고 있는지?
가볍게 안티 MySQL이 될지도…

결론 (MySQL에서의 실현 방법)



이 기사를 볼 수 있다고 생각합니다.
h tps : // ゔ ぁ ふ y…
1. deleted_at 열을 추가한 후,
2. deleted_at에 Null이 아닌 활성 사용자에게도 특정 값을 부여하면,
2 컬럼에서의 UNIQUE를 실현해 (dleted_at가 NULL이면 실현하지 않는다)
3. 간단하게 논리 삭제와 일의 제약을 양립

최고로 좋은 기사에 감사드립니다! !

구현



[환경]
- 루비 : 2.6.6p146
- Rails: 6.0.3.3
- MySQL : 8.0.21
- mysql2 : 0.5.3
- devise: 4.7.2
- paranoia: 2.4.2

준비



환경 구축이나 devise, paranoia 도입 등의 기본 부분의 구현은 그 밖에 많은 기사가 나오고 있으므로 할애합니다.
devise 표준의 회원등록・탈퇴기능 등이 동작하는 전제입니다.

1. 설정 파일 paranoia.rb 만들기



config/initializers/paranoia.rb
# ユーザー退会後の論理削除・一意制約を両立させるための処理
# 非削除レコードはdeleted_at = '0000-01-01 00:00:00'
# 削除済みレコードはdeleted_at != '0000-01-01 00:00:00'
Paranoia.default_sentinel_value = DateTime.new(0)

2. migration에서의 index 변경



기본 사용자 테이블의 색인을 변경하는 마이그레이션 파일 작성


rails g Change_Index_To_Users

작성한 마이그레이션 파일을 다음과 같이 변경



일단 기본적으로 생성된 이메일 색인을 삭제합니다.
새로 [email, deleted_at]에서 unique 색인 생성

db/migrate/202009220000000.rb
class ChangeIndexUniuqueToUsers < ActiveRecord::Migration[6.0]
  def change
    remove_index :users, :email
    add_index :users, [:email,:deleted_at], unique: true
  end
end

migration


rails db:migrate

3. Validation 추가



애플리케이션 레벨에서 유효성 검증 추가



app/models/user.rb
class User < ActiveRecord::Base
  acts_as_paranoia
  validates :email, uniqueness: { scope: :deleted_at }  

4. 동작 확인



rails 콘솔 또는 rails 서버를 시작 실제로 사용자 작성, 탈퇴, 같은 주소로 재등록을 실시하여 DB를 확인합니다.


무사히 같은 주소로의 재등록에 성공했습니다! !
다른 뭔가 좋은 방법 등 있으면 꼭 가르쳐주세요 ~!

좋은 웹페이지 즐겨찾기