How can i remove the last element from an ActiveRecord_Relation in rails?
e.g. if I set:
@drivers = Driver.all
I can add a another Driver object called @new_driver to @drivers by doing:
@drivers << @new_driver
But how can I remove an object from @drivers?
The delete method doesn't seem to work, i.e.
@drivers.delete(0)
If you are using Rails 5 and above, the following solution will work. Show activity on this post. Deleting a row from a particular table or a record set from a table is pretty simple, from your console all you need to do is grab the record set by its Id then delete or destroy it.
Active Record Relation. The cache key is built with a fingerprint of the sql query, the number of records matched by the query and a timestamp of the last updated record. When a new record comes to match the query, or any of the existing records is updated or deleted, the cache key changes.
This can accelerate the problem of running out of integers, if the underlying table is still stuck on a primary key of type int (note: All Rails apps since 5.1+ have defaulted to bigint, which is not liable to this problem).
This is the documentation you need:
@group.avatars << Avatar.new
@group.avatars.delete(@group.avatars.last)
--
.destroy
The problem you've got is you're trying to use collection
methods on a non-collection object. You'll need to use the .destroy
ActiveRecord method to get rid of the record from the database (and consequently the collection):
@drivers = Driver.all
@drivers.last.destroy
--
Scope
.delete
will remove the record from the DB
If you want to pull specific elements from the db to populate the @drivers
object, you'll need to use a scope
:
#app/models/driver.rb
Class Driver < ActiveRecord::Base
scope :your_scope, -> { where column: "value" }
end
This will allow you to call:
#app/controllers/drivers_controller.rb
def index
@drivers = Driver.your_scope
end
I think you're getting the MVC programming pattern confused - data manipulation is meant to happen in the model
, not the controller
Very late too, but I arrived here looking for a fast answer and finished by thinking by myself ;)
Just to clarify about the different answers and the Rails 6.1 comment on accepted answer:
The OP wanted to remove one entry from a query, but NOT remove it from database, so any answer with delete
or destroy
is just wrong (this WILL delete data from your database !!).
In Ruby (and therefore Rails) convention, shebang methods (ending with !
) tend to alter the given parameter. So reject!
would imply modifying the source list ... but an ActiveRecord_Relation
is basically just a query, NOT an array of entries !
So you'd have 2 options:
@drivers.where.not(id: @driver_to_remove) # This still is an ActiveRecord_Relation
reject
(NO shebang) on your query to transform it into an Array and "manually" remove the entry you don't want:@drivers.reject{ |driver| driver == @driver_to_remove}
# The `reject` forces the execution of the query in DB and returns an Array)
On a performance point of view, I would personally recommend the first solution as it would be just a little more complex against the DB where the latter implies looping on the whole (eventually large) array.
You can use the reject!
method, this will remove the object from the collection without affecting the db
for example:
driver_to_delete = @driver.first # you need the object that you want removed
@drivers.reject!{|driver| driver == driver_to_delete}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With