Khi hủy tài nguyên an toàn, tôi muốn đảm bảo một vài điều trước khi tôi cho phép hoạt động phá hủy tiếp tục? Về cơ bản, tôi muốn có khả năng ngừng hoạt động phá hủy nếu tôi lưu ý rằng làm như vậy sẽ đặt cơ sở dữ liệu ở trạng thái không hợp lệ? Không có callbacks xác nhận về một hoạt động phá hủy, do đó, làm thế nào một "xác nhận" cho dù một hoạt động phá hủy nên được chấp nhận?Làm cách nào để 'xác thực' khi hủy đường ray
Trả lời
Bạn có thể tăng ngoại lệ mà bạn bắt được. Rails kết thúc tốt đẹp xóa trong một giao dịch, giúp các vấn đề.
Ví dụ:
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
Hoặc bạn có thể sử dụng callback before_destroy. Cuộc gọi lại này thường được sử dụng để hủy các bản ghi phụ thuộc, nhưng bạn có thể ném một ngoại lệ hoặc thêm một lỗi thay vào đó.
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
bây giờ sẽ trả về false, và myBooking.errors
sẽ được áp dụng vào trở lại.
Um, có gì sai với chỉ kiểm tra các hiệp hội booking_payments cần được xác định trên mô hình mà thay vì gọi BookingPayment .count, dẫn đến mã xấu? –
Tôi đã chỉnh sửa trả lời của mình cho phù hợp. Xin lỗi, tôi đã kéo cái này ra khỏi một số mã cũ ... –
Lưu ý rằng bây giờ nó nói "... ok, tiếp tục và tiêu diệt", bạn cần đặt "siêu", vì vậy phương pháp phá hủy ban đầu thực sự được gọi. –
Bạn cũng có thể sử dụng gọi lại before_destroy để tăng ngoại lệ.
Các liên kết ActiveRecord has_many và has_one cho phép tùy chọn phụ thuộc để đảm bảo các hàng trong bảng có liên quan bị xóa khi xóa, nhưng điều này thường giữ cho cơ sở dữ liệu của bạn sạch hơn là ngăn không hợp lệ.
+1 cho "\ _" không nhận ra rằng đó là một tùy chọn trên SO – ahsteele
Một cách khác để chăm sóc dấu gạch dưới, nếu chúng là một phần của tên hàm hoặc tương tự, là quấn chúng vào các dấu gạch chéo ngược. Điều đó sẽ hiển thị sau đó dưới dạng mã, 'like_so'. –
Bạn có thể quấn phá hủy hành động trong một "nếu" tuyên bố trong bộ điều khiển:
def destroy # in controller context
if (model.valid_destroy?)
model.destroy # if in model context, use `super`
end
end
đâu valid_destroy? là một phương thức trên lớp mô hình của bạn trả về true nếu các điều kiện hủy phá bản ghi được đáp ứng.
Có phương pháp như vậy cũng sẽ cho phép bạn ngăn hiển thị tùy chọn xóa cho người dùng - điều này sẽ cải thiện trải nghiệm người dùng khi người dùng không thể thực hiện thao tác bất hợp pháp.
Vòng lặp vô hạn, bất kỳ ai? – jenjenut233
bắt tốt, nhưng tôi đã giả định phương pháp này là trong bộ điều khiển, trì hoãn mô hình. Nếu nó là trong mô hình chắc chắn sẽ gây ra vấn đề –
hehe, xin lỗi bout rằng ... Tôi thấy những gì bạn có nghĩa là, tôi chỉ thấy "phương pháp trên lớp mô hình của bạn" và nhanh chóng nghĩ "uh oh", nhưng bạn đúng - tiêu diệt trên bộ điều khiển, điều đó sẽ hoạt động tốt. :) – jenjenut233
chỉ là một lưu ý:
Đối với đường ray 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
Một vấn đề với cách tiếp cận này là callback before_destroy có vẻ được gọi là * sau khi * tất cả các booking_payments đã bị phá hủy. – sunkencity
Vé liên quan: https://github.com/rails/rails/issues/3458 @sunkencity bạn có thể khai báo before_destroy trước khi tuyên bố kết hợp để tạm thời tránh điều này. – lulalala
tôi đã kết thúc sử dụng mã từ vào đây để tạo một ghi đè can_destroy trên activerecord: 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
này đã cho biết thêm lợi ích của việc làm cho nó tầm thường để ẩn/hiển thị nút xóa trên ui
Tôi có các lớp hoặc các mô hình
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
Bây giờ khi bạn xóa một doanh nghiệp quá trình này xác nhận nếu có những sản phẩm liên quan đến doanh nghiệp Lưu ý: Bạn phải viết này trong top của lớp để xác nhận nó Đầu tiên.
Đó là những gì tôi đã làm với Rails 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
Đây là một bài viết hay giải thích hành vi này trong Rails 5: http://blog.bigbinary.com/2016/02/13/rails-5-does-not-halt-callback-chain-when-false-is- return.html –
Sử dụng ActiveRecord xác nhận bối cảnh trong Rails 5.
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
- 1. Làm cách nào để xác thực ngày trong đường ray?
- 2. Làm cách nào để chỉ định và xác thực enum trong đường ray?
- 3. Xác thực biểu mẫu đường ray
- 4. Xác thực đường ray qua chuyển hướng
- 5. Cách đánh dấu trường trên lỗi xác thực đường ray
- 6. Làm thế nào để nội tuyến css khi sử dụng đường ray tài sản đường ray
- 7. Đường ray, phá hủy so với xóa?
- 8. Xác thực đường ray qua các ứng dụng/máy chủ
- 9. Đường ray: Cách xác thực định dạng chỉ khi có giá trị?
- 10. Làm cách nào để chuyển đổi giữa đường ray 3.2.13 và đường ray 4.0.0?
- 11. Đường ray - Cách xác thực trường chỉ khi một trường khác có giá trị nhất định?
- 12. Làm thế nào để trống/hủy một phiên trong đường ray?
- 13. Đường ray: xác thực mã thông báo từ đầu
- 14. Cách xác định đường dẫn tùy chỉnh trong đường ray?
- 15. Làm thế nào để biết khi nào mô hình tự động bị phá hủy bởi: phụ thuộc =>: phá hủy trong đường ray?
- 16. Tôi làm cách nào để xác thực người dùng khỏi các đường ray có tính năng tự động?
- 17. đường ray - cách làm mới liên kết sau khi lưu
- 18. Làm cách nào để sử dụng nhiều bộ đệm trong đường ray? (thực tế)
- 19. Làm cách nào để xác định trình trợ giúp định tuyến riêng trong đường ray 3?
- 20. Đường ray: Thông báo xác thực tùy chỉnh
- 21. Làm cách nào để xác định chiều cao dòng với Prawn khi tạo pdf trong ứng dụng đường ray?
- 22. đường ray fields_for không hiển thị sau khi lỗi xác thực trên biểu mẫu lồng nhau
- 23. Làm cách nào để xóa đối tượng con khi cha mẹ bị xóa trong đường ray?
- 24. Làm cách nào để xóa đường viền ButtonChrome (khi xác định mẫu của đường viền)?
- 25. Lỗi // Cách sử dụng: đường ray mới APP_PATH [tùy chọn] // khi chạy 'đường ray máy chủ'
- 26. Cách sử dụng nút radio chính xác trong đường ray?
- 27. Làm thế nào để chuyển các truy vấn để thực hiện hiệu quả trong đường ray?
- 28. làm cách nào để xác thực sự hiện diện của một trường chỉ khi một trường khác được chỉnh sửa trong đường ray?
- 29. đường ray content_for không được thực thi khi thực hiện hiển thị?
- 30. Làm thế nào để làm cho đường ray f.select chọn
liên quan: http://stackoverflow.com/questions/5520320/validate-before-destroy –