2010-10-29 33 views
36

Tôi đã xem qua hướng dẫn Ruby on Rails và tôi dường như không thể tìm ra cách ngăn chặn ai đó xóa hồ sơ Gốc nếu có con. Ví dụ. Nếu cơ sở dữ liệu của tôi có KHÁCH HÀNG và mỗi khách hàng có thể có nhiều ORDERS, tôi muốn ngăn người khác xóa khách hàng nếu có bất kỳ đơn hàng nào trong cơ sở dữ liệu. Họ chỉ có thể xóa một khách hàng nếu nó không có đơn đặt hàng.Làm cách nào để ngăn chặn việc xóa phụ huynh nếu có hồ sơ con?

Có cách nào khi xác định mối liên hệ giữa các mô hình để thực thi hành vi này không?

Trả lời

43

Bạn có thể làm điều này trong một callback:

class Customer < ActiveRecord::Base 
    has_many :orders 
    before_destroy :check_for_orders 

    private 

    def check_for_orders 
    if orders.count > 0 
     errors.add_to_base("cannot delete customer while orders exist") 
     return false 
    end 
    end 
end 

EDIT

thấy this answer kiếm một cách tốt hơn để làm điều này.

+5

Đây là cách tốt nhất. Đó là sạch sẽ nhất, và đó chính xác là nơi tôi sẽ tìm kiếm một bộ lọc như vậy nếu tôi đang làm việc trên mã của bạn. Trả về "false" trong callback là những gì bảo các đường ray không tiếp tục hành động. –

+0

'has_any ...?' :) –

+0

Cảm ơn, Joe. Không, tôi không phát minh ra loại liên kết mới ... – zetetic

0

Hãy thử sử dụng filters để móc trong mã tùy chỉnh trong khi xử lý yêu cầu.

0

Một khả năng là tránh cung cấp cho người dùng của bạn liên kết để xóa trong trường hợp này.

link_to_unless [email protected]? 

Một cách khác sẽ được xử lý này trong điều khiển của bạn:

if [email protected]? 
    flash[:notice] = "Cannot delete a customer with orders" 
    render :action => :some_action 
end 

Hoặc, như Joe gợi ý, before_filters có thể làm việc tốt ở đây và có lẽ sẽ là một chặng đường nhiều DRY hơn để làm điều này, đặc biệt nếu bạn muốn loại hành vi này cho nhiều mô hình hơn là chỉ Khách hàng.

81
class Customer < ActiveRecord::Base 
    has_many :orders, :dependent => :restrict # raises ActiveRecord::DeleteRestrictionError 

Chỉnh sửa: như của Rails 4.1, :restrict không phải là một lựa chọn hợp lệ, và thay vào đó bạn nên sử dụng một trong hai :restrict_with_error hoặc :restrict_with_exception

Eg .:

class Customer < ActiveRecord::Base 
    has_many :orders, :dependent => :restrict_with_error 
+0

Cảm ơn! Sạch sẽ;) Tôi nghĩ rằng ref. tính toàn vẹn được bật theo mặc định trong Rails ... – luigi7up

+1

Có thể tùy chỉnh thông báo hạn chế không? –

+2

Câu trả lời này có thể được cập nhật để phản ánh những thay đổi trong Rails 4.1 trở lên không? "Đã xóa hỗ trợ cho tùy chọn không được chấp nhận: hạn chế cho: phụ thuộc vào các liên kết". http://edgeguides.rubyonrails.org/4_1_release_notes.html. Tùy chọn: phụ thuộc phải là một trong các [: destroy,: delete_all,: nullify,: restrict_with_error,: restrict_with_exception] – Marklar

Các vấn đề liên quan