before_destroy
OmniAuthログインできるサービスをつくるとき、facebook,twitter,github,googleなど複数のプロバイダーとアカウントを連携させることがあります。
でも、すべてのアカウント連携を解除してしまうとセッションが切れた時にログインできなくなってしまうので少なくとも一つの認証用アカウントが必要です。
そんなときに、destroyメソッドにバリデーションをつけるために、Rails4まではbefore_destroyを使い、return false
を返すとコールバックがストップしてくれるのでそうしてました。
rails5からはthrow :abort
になりました。
今まで通りerrors.full_messages
などが使えます。
social_profile.rb
class SocialProfile < ActiveRecord::Base
belongs_to :user
store :other
validates :uid, uniqueness: { scope: :provider }, length: { in: 6..128 }
validates :provider, inclusion: { in: Settings.auth_config.keys.map(&:to_s) }
include Logic::SocialProfile
include Logic::SocialProfile::InitializeWithCallbackInfo
# before_destroyでdestroyメソッドを実行する前にバリデーションをかけます
before_destroy :least_one
private
def least_one
if self.user.social_profiles.count == 1
errors.add :base, '少なくとも1つ、ログイン用の認証が必要です'
# return false ではなく throw :abort
throw :abort
end
end
end
railsは仕様変更も楽しいですね