6

Tôi đang sử dụng plugin "actions_as_tree" cho tính năng chuỗi tin nhắn của người dùng trên trang web của mình. Tôi có một phương pháp giúp xóa các thư đã chọn có thể. Các tin nhắn không thực sự bị xóa. Các cột sender_status hoặc recipient_status của họ được đặt thành 1 tùy thuộc vào người dùng là người gửi hoặc người nhận thư.Làm thế nào tôi có thể hủy bỏ_all hoặc xóa các bản ghi trừ một bản ghi trên ruby ​​trên đường ray?

Dù sao nếu cả hai người dùng có trạng thái đó được đặt thành một thì dòng cuối cùng đó đảm bảo rằng hàng thư được di chuyển hoàn toàn từ cơ sở dữ liệu. Bây giờ điều này là tốt miễn là nó không phải là tin nhắn cha mẹ bị xóa. Nếu thông báo cha bị xóa thì những đứa trẻ chưa được chọn để xóa sẽ không thể truy cập được nữa.

Đây là phương pháp:

 def delete_all_users_selected_messages(message_ids, user_id, parent_id) 
      Message.where(:id => message_ids, :sender_id => user_id).update_all(:sender_status => 1) 
      Message.where(:id => message_ids, :recipient_id => user_id).update_all(:recipient_status => 1) 
      Message.delete_all(:sender_status => 1, :recipient_status => 1, :parent_id => parent_id).where("id != ?", parent_id) 
     end 

Đó là khá rõ ràng những gì tôi đang cố gắng làm. Tôi cần phải bỏ cha mẹ. Vì vậy, nơi khóa chính bằng với parent_id có nghĩa là hàng đó là một parent (thường là parent_id là nil nhưng tôi cần nó được đặt thành giá trị khóa chính cho một số lý do khác, câu chuyện dài và không quan trọng). Dù sao là có một câu lệnh SQL tôi có thể thêm vào cuối dòng cuối cùng trong phương pháp tat? Để đảm bảo rằng nó chỉ xóa các thư có id của hàng không bằng parent_id?

Tôi có thể sắp xếp hàng parent_id để không bao giờ được phép xóa trừ khi chuỗi thực tế (bảng MessageThreads tham chiếu đến các cuộc hội thoại bảng tin) bị xóa.

Bất kỳ cách nào tôi có thể thực hiện để hàng này bị bỏ qua khi phương thức delete_all đó chạy?

Trân trọng

Trả lời

2

Điều này làm việc cho tôi cuối cùng.

Message.where('id != ? AND parent_id = ?', parent_id, parent_id).where(:sender_status => 1, :recipient_status => 1).delete_all 

Về cơ bản trả về tất cả thư của cuộc hội thoại cụ thể đó ngoại trừ cuộc hội thoại id == parent_id. Ở đâu id == parent_id có nghĩa là nó là một thông báo cha.

2

Tại sao không sử dụng liên kết từ hồ sơ gốc, nội dung như thế này?

Message.where(:id => parent_id).first 
    .children.where(:sender_status => 1, :recipient_status => 1) 
    .delete_all 
+0

Có phương thức không xác định trẻ em vì vậy tôi đã thử Message.where (: id => parent_id) .first.children.delete_all (: sender_status => 1,: recipient_status => 1) .. sau đó nhận được số lượng sai đối số 1 cho 0 – LondonGuy

+0

Có lỗi tôi đã bỏ lỡ 'đầu tiên'. Bạn có thể tách chuỗi này thành nhiều câu lệnh để chúng tôi có thể tìm thấy lỗi xảy ra ở đâu không? Ví dụ, lấy bản ghi cha trước, sau đó gọi 'con ....'. –

+0

Cập nhật câu trả lời. delete_all không chấp nhận tham số. –

1

tôi sẽ xem xét một cách tiếp cận hơi khác nhau và có mô hình có mối quan hệ has_many:dependent => destroy với nó, ví dụ
User has_many :messages, :dependent => :destroy Bằng cách đó, bạn không gặp phải sự cố 'ghi lại trẻ mồ côi lơ lửng' mà bạn mô tả.

Tôi sẽ thử và tiếp cận theo cách này thay vì nghĩ 'tất cả các bản ghi ngoại trừ'.
Tôi không biết nếu có điều gì đó tôi không giải quyết nhưng đây là những gì đến để tìm cho các vấn đề mô tả.

+0

Mô hình tin nhắn has_one message_thread và mô hình message_thread thuộc về mẫu tin nhắn. Tôi không chắc chắn làm thế nào để thực hiện phá hủy phụ thuộc với những gì tôi đã làm. Tôi đã sử dụng nó với tính năng micropost và bình luận của tôi. Về cơ bản khi micropost chính bị xóa tất cả các bình luận của nó cũng vậy. Với hệ thống tin nhắn này, nó khá phức tạp vì message_thread thuộc_to tin nhắn .. nếu tôi gọi message_thread.message thông báo cha sẽ xuất hiện nếu tôi gọi message.message_thread message_thread tham chiếu đến hội thoại (cha và con trong bảng tin nhắn) xuất hiện. – LondonGuy

+0

Vì vậy, nếu tôi đã sử dụng tiêu diệt phụ thuộc trong mô hình tin nhắn message_thread sẽ bị xóa các tin nhắn phụ huynh sẽ bị xóa nhưng sẽ không phải tất cả các trẻ em được trái? cũng nếu tôi làm điều này theo cách khác vòng và xóa một message_thread nó sẽ không chỉ cần xóa các tin nhắn phụ huynh và để lại cho trẻ em? Tôi không hoàn toàn chắc chắn cách behavior_as_tree hoạt động ở chế độ nền. – LondonGuy

11

Ngày nay trong Rails 4, bạn có thể làm:

Model.where.not(attr: "something").delete_all 

Model.where.not(attr: "something").destroy_all 

Và đừng quên về sự khác biệt:

  • destroy_all: Các đối tượng liên quan bị phá hủy cùng đối tượng này bằng cách gọi phương thức destroy của chúng. Instantiates tất cả các hồ sơ và phá hủy chúng cùng một lúc, do đó, với một tập dữ liệu lớn, điều này có thể chậm
  • delete_all: Tất cả các đối tượng liên quan sẽ bị hủy ngay lập tức mà không cần gọi phương thức destroy của chúng. Gọi lại không được gọi.
+3

Cần lưu ý rằng các cuộc gọi lại không được kích hoạt trên 'delete_all', do đó nếu bạn có các phụ thuộc mà bạn mong muốn bị xóa, chúng sẽ không bị xóa. Sử dụng 'destroy_all' thay cho nhu cầu đó. – cdownard

+1

Đó là sự thật, quên đăng về điều đó, cảm ơn bạn! – igmarin

+1

Điều này có lẽ là câu trả lời. Giả sử cập nhật để destroy_all. – brntsllvn

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