Why can't I use Record.all.destroy in Rails?

I'm currently starting to learn Ruby and Ruby on Rails. I found that in the records table I can find the record with id 5 and delete it using the following code:

Record.find(5).destroy

It makes sense - I hook on methods to find a record and destroy it. However, if I want to destroy all the records in the table, the logical command will be as follows: the selector all selects all the records in the table:

Record.all.destroy

And that returns a NoMethodError! I know that I can use Record.destroy_all or Record.delete_all to accomplish this task, however I would like to know why I cannot just use the most logical choice instead of looking for things like delete_all . I am new to this structure, so it is quite possible that I missed something fundamental here.

Thanks for any answers in advance.

+7
source share
5 answers

It was a design decision. DataMapper took your approach . Being forced to write destroy_all explicitly can be tedious, but it also will not allow you to do what you really do not need (i.e. delete everything in the table, for example x = User; ...; x.destroy ).

+14
source

I agree that it would be logical to do this. Technically speaking, Record.all returns a collection (or proxy to the collection) that does not implement the destroy method.

+3
source

If you

 Record.find(5) 

this returns a record object / instance that represents the data in a row in your table. Then you call the #destroy method for this object, which is determined by your recording model.

If you

 Record.all 

returns an Array object. In order for you to then call #destroy in an array, you would need to set the Ruby core Array core marker for the #destroy method.

+1
source

The easiest way to avoid Record.destroy_all is Record.all.each {|r| r.destroy} Record.all.each {|r| r.destroy} . This may somewhat suit your API design requirements, but should be much slower than the first option.

+1
source

Actually you can (in some way). Since .all returns an array, not an active write relation, what exactly could you delete? I would not say that Record.all.destroy is logical at all - are you deleting an array object?

One thing you can do is map the resulting array, and since map accepts proc ( & ), you can execute this proc for every object in your array.

 Record.all.map(&:destroy) 

Note that this will cause callbacks for all of your objects, which may be slower than you planned. If you want to avoid callbacks, you can map the corresponding destructive method instead of destroying it. (hint :: delete)

Alternatively, you can simply:

 Record.destroy_all or Record.delete_all 

as you stated in your question.

0
source

All Articles