2008-12-01 23 views
64

Tôi biết điều này có thể trên Internet ở đâu đó nhưng tôi không thể tìm thấy câu trả lời ở đây trên Stackoverflow vì vậy tôi nghĩ rằng tôi có thể tăng cường cơ sở kiến ​​thức ở đây một chút.Tôi có thể thiết lập tính năng Xóa tầng trong Rails không?

Tôi là người mới tham gia Ruby và Rails nhưng công ty của tôi đang đầu tư khá nhiều vào nó nên tôi đang cố gắng tìm hiểu chi tiết hơn một chút. Rất khó để tôi thay đổi suy nghĩ của mình để thiết kế một ứng dụng từ "mô hình" thay vì từ cơ sở dữ liệu, vì vậy tôi đang cố gắng tìm hiểu cách thực hiện tất cả các công việc thiết kế mà tôi đã thực hiện ở mức độ cổ điển Cơ sở dữ liệu trong mô hình Rails thay thế.

Vì vậy, nhiệm vụ gần đây nhất mà tôi đã cung cấp cho mình là tìm ra cách cấu hình mô hình cơ sở dữ liệu Rails để thực hiện xóa tầng? Có cách nào dễ dàng để làm điều này? Hoặc tôi sẽ phải đi vào MySql và thiết lập này?

Cảm ơn.

-Matt

Trả lời

79

bạn cũng có thể đặt tùy chọn: phụ thuộc thành: delete_all. : delete_all sẽ phát hành một câu lệnh SQL để xóa tất cả các bản ghi con. vì điều này bằng cách sử dụng: delete_all có thể cung cấp cho bạn hiệu suất tốt hơn.

has_many :memberships, dependent: :delete_all 
+8

Giải thích của bạn gây nhầm lẫn. Một câu lệnh SQL đơn sẽ được sử dụng, nhưng phương thức hủy sẽ không được gọi cho mỗi hàng con. Bạn phải sử dụng destroy_all cho điều đó. –

+0

@John - hy vọng các chỉnh sửa sẽ làm sáng tỏ sự nhầm lẫn. cảm ơn vì đã chỉ ra điều đó. –

+0

@Mike - tốt hơn nhiều, cảm ơn. –

58

Vâng bạn có thể, nếu bạn đang sử dụng một mối quan hệ như has_many bạn chỉ cần làm điều này

has_many :memberships, dependent: :destroy 
+0

Dan, Vì vậy, tôi đoán câu hỏi tiếp theo của tôi là nếu tôi chạy một lệnh di chuyển db sẽ thực sự thiết lập đó trong db?Hoặc là tầng được xử lý hoàn toàn bằng đường ray? –

+0

Có, nó được xử lý bằng đường ray. (Do đó, hãy đảm bảo bạn thực sự luôn cần xóa mọi hàng có liên quan.) –

+0

@Matt - dòng has_many phải nằm trong lớp mô hình của bạn, quá trình di chuyển sẽ không thêm cho bạn. – Gareth

6

Nó trông giống như plugin này có thể cung cấp cho bạn những gì bạn đang tìm kiếm nếu bạn muốn các tầng delete phản ánh trong cấu trúc cơ sở dữ liệu thực tế:

http://www.redhillonrails.org/foreign_key_migrations.html

Format cho việc sử dụng này trong một sự chuyển đổi sẽ somethi ng như thế này:

create_table :orders do |t| 
    t.column :customer_id, :integer, :on_delete => :set_null, :on_update => :cascade 
    ... 
end 
+5

Liên kết đó đã chết nhưng đây là một giải pháp thay thế mới hơn: http://github.com/matthuhiggins/foreigner – gdelfino

9

Chỉ cần nhớ rằng delete_all sẽ không thực hiện bất kỳ cuộc gọi lại nào (như before_destroy và after_destroy) trên hồ sơ con.

9

Trái với câu trả lời được cung cấp, tôi khuyên bạn cũng nên thực hiện việc này ở cấp cơ sở dữ liệu. Trong trường hợp bạn có các quy trình khác nhau hoặc môi trường đa luồng có thể xảy ra là các bản ghi không được xóa đúng cách. Hơn nữa, khóa ngoại vi cơ sở dữ liệu giúp mọi thứ nhanh hơn khi xóa nhiều dữ liệu.

Giống như trong câu trả lời gợi ý làm điều này:

has_many :memberships, dependent: :delete_all 

Tuy nhiên cũng hãy chắc chắn để thiết lập một foreign_key vào cuộc di cư. Bằng cách đó, cơ sở dữ liệu sẽ tự động xóa các bản ghi cho bạn.

Để vô hiệu hóa các giá trị khi một thành viên bị xóa, giả sử bạn có một mô hình người dùng:

add_foreign_key :users, :memberships, on_delete: :nullify 

Bạn cũng có thể xóa tất cả các mô hình bất cứ khi nào một thành viên bị xóa

add_foreign_key :users, :memberships, on_delete: :cascade 
Các vấn đề liên quan