문제

편안한 자원을 파괴 할 때 파괴 작업이 계속되기 전에 몇 가지를 보장하고 싶습니다. 기본적으로, 데이터베이스가 무효 상태에있을 것이라고 주목하면 파괴 작업을 중지 할 수있는 능력을 원하십니까? 파괴 작업에는 검증 콜백이 없으므로 파괴 작업을 수락 해야하는지 여부를 어떻게 "검증"합니까?

도움이 되었습니까?

해결책

당신은 당신이 잡는 예외를 제기 할 수 있습니다. Rails는 거래에 삭제를 마무리하여 문제를 돕습니다.

예를 들어:

class Booking < ActiveRecord::Base
  has_many   :booking_payments
  ....
  def destroy
    raise "Cannot delete booking with payments" unless booking_payments.count == 0
    # ... ok, go ahead and destroy
    super
  end
end

또는 prever_destroy 콜백을 사용할 수 있습니다. 이 콜백은 일반적으로 종속 레코드를 파괴하는 데 사용되지만 예외를 던지거나 오류를 추가 할 수 있습니다.

def before_destroy
  return true if booking_payments.count == 0
  errors.add :base, "Cannot delete booking with payments"
  # or errors.add_to_base in Rails 2
  false
  # Rails 5
  throw(:abort)
end

myBooking.destroy 이제 false를 반환하고 myBooking.errors 반환시 채집됩니다.

다른 팁

그냥 메모 :

레일 3

class Booking < ActiveRecord::Base

before_destroy :booking_with_payments?

private

def booking_with_payments?
        errors.add(:base, "Cannot delete booking with payments") unless booking_payments.count == 0

        errors.blank? #return false, to not destroy the element, otherwise, it will delete.
end

내가 레일 5로 한 일입니다.

before_destroy do
  cannot_delete_with_qrcodes
  throw(:abort) if errors.present?
end

def cannot_delete_with_qrcodes
  errors.add(:base, 'Cannot delete shop with qrcodes') if qrcodes.any?
end

ActivereCord Associations Has_many 및 Has_one은 관련 테이블 행이 삭제에서 삭제 될 수있는 종속 옵션을 허용하지만 일반적으로 데이터베이스가 유효하지 않도록 데이터베이스를 깨끗하게 유지하는 것입니다.

컨트롤러의 "if"문으로 파괴 동작을 래핑 할 수 있습니다.

def destroy # in controller context
  if (model.valid_destroy?)
    model.destroy # if in model context, use `super`
  end
end

어디에 valid_destroy? 레코드 파괴 조건이 충족되면 TRUE를 반환하는 모델 클래스의 메소드입니다.

이와 같은 방법을 사용하면 사용자에게 삭제 옵션이 표시되는 것을 방지 할 수 있습니다. 이는 사용자가 불법 작업을 수행 할 수 없으므로 사용자 경험을 향상시킵니다.

여기에서 코드를 사용하여 ActiveRecord에서 CAN_DESTROY OVERMED를 작성했습니다.https://gist.github.com/andhapp/1761098

class ActiveRecord::Base
  def can_destroy?
    self.class.reflect_on_all_associations.all? do |assoc|
      assoc.options[:dependent] != :restrict || (assoc.macro == :has_one && self.send(assoc.name).nil?) || (assoc.macro == :has_many && self.send(assoc.name).empty?)
    end
  end
end

이것은 UI에서 삭제 버튼을 숨기거나 표시하는 것이 사소한 이점이 있습니다.

이전 _destroy 콜백을 사용하여 예외를 제기 할 수도 있습니다.

이 수업이나 모델이 있습니다

class Enterprise < AR::Base
   has_many :products
   before_destroy :enterprise_with_products?

   private

   def empresas_with_portafolios?
      self.portafolios.empty?  
   end
end

class Product < AR::Base
   belongs_to :enterprises
end

이제 엔터프라이즈를 삭제할 때이 프로세스는 기업과 관련된 제품이 있는지 확인합니다. 참고 : 먼저 검증하려면 클래스 상단에 이것을 작성해야합니다.

레일 5에서 ActivereCord 컨텍스트 검증을 사용하십시오.

class ApplicationRecord < ActiveRecord::Base
  before_destroy do
    throw :abort if invalid?(:destroy)
  end
end
class Ticket < ApplicationRecord
  validate :validate_expires_on, on: :destroy

  def validate_expires_on
    errors.add :expires_on if expires_on > Time.now
  end
end

나는 이것이 뒷받침되기를 바라고 있었기 때문에 그것을 추가하기 위해 레일 문제를 열었습니다.

https://github.com/rails/rails/issues/32376

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top