How can I destroy_all or delete_all entries except one in ruby ​​on rails?

I use the "actions_as_tree" plugin for my user message flow feature on my website. I have a method that allows me to delete selected messages. Messages are not actually deleted. Their sender_status or recipient_status columns are set to 1 depending on which user is the sender or recipient of the message.

In any case, if both users have the status set to one, then the last line ensures that the message line is completely moved from the database. Now this is normal until the parent message is deleted. If the parent message is deleted, children who were not selected for deletion will no longer be available.

Here is a way:

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 

Obviously what I'm trying to do. I need the parent to be ignored. So, where the primary key is parent_id, this means the row is the parent (usually parent_id is zero, but I need it to be set to the value of the primary keys for some other reason, a long story and it doesn't matter). Anyway, is there an SQL statement that I can add to the end of the last line in the tat method? To make sure it only deletes messages where the row id is not equal to parent_id?

I can arrange for the parent_id line to never be allowed to be deleted if the actual thread (the MessageThreads table that refers to the message message tables) is deleted.

How can I do this so that this parent line is ignored when this delete_all method is run?

respectfully

+6
source share
4 answers

It worked for me in the end.

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

Basically returns all the messages of this particular conversation, except those where id == parent_id. Wherever id == parent_id is, this means it's a parent message.

+2
source

Currently in Rails 4 you can:

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

and

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

And don't forget the differences:

  • destroy_all: related objects are destroyed next to this object by calling their destroy method. Creates all records and destroys them one at a time, so with a large dataset this can be slow.
  • delete_all: all related objects are destroyed immediately without calling the destroy method. Callbacks are not called.
+11
source

Why not use the association from the parent record, something like this?

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

I would consider a slightly different approach and have a model with a has_many relation with :dependent => destroy with it, for example,
User has_many :messages, :dependent => :destroy Thus, you will not get the "dangling orphaned record" problem you described.

I would try to approach this path, instead of thinking "all entries except."
I don’t know if there is something that I am not talking about, but this is what I need to find for the described problem.

+1
source

Source: https://habr.com/ru/post/909027/


All Articles