I was working in a method that needed to remove an element from the resultset that was returned when I called this:
@widgets = Widget.active #active is just a scope I created in the Widget model @widgets.delete(some_widget)
I would expect this to delete the object from the Array and my view would not render that particular element in the collection. But I found this element being deleted from the database. How is that possible??? It turns out that this collection was still an ActiveRecord::Relation object and not an Array. Since the new query API lazy loads the queries, they are not executed until they get to the view… and not turned into an Array object until they get to the view. I was trying to remove an element from the Array in my controller. To figure this out, I just put a debug statement to return the class of @widgets.
p @widgets.class #=>ActiveRecord::Relation
In order to force the Relation into an Array, you can call the “all” function which will eager load it in the controller.
@widgets = Widget.active.all #call all to eager load @widgets.delete(some_widget)
This time, “some_widget” was only removed from the @widgets Array and not deleted in my database.




#1 by Anka on March 16, 2011 - 1:39 am
Quote
Thank you! This was really helpful!
#2 by Adam Rubin on March 24, 2011 - 12:17 pm
Quote
I was just losing my mind over something like this. Thanks for sharing!
#3 by cowboycoded on March 24, 2011 - 12:25 pm
Quote
I know.. quite annoying and dangerous!!! Took me a quite a while to debug this one.
#4 by caro on October 19, 2011 - 4:33 pm
Quote
Hi! Thanks for the article. I am new to rails so please excuse my lack of basic knowledge. I have:
@products = Product.search(query)
…
@products.delete()
So according to you, I need to call @products = Product.all. But if I already have my ActiveRecord with the items I want, how do I convert it to an array?
Many thanks!
Trackback: adult match maker
#5 by Travis Pearl on September 18, 2012 - 10:21 am
Quote
That was a confusing gotcha – controller kept deleting objects on page refresh (delete was being called in controller on elements of the collection)! Thanks for clarifying this.