How to destroy Ruby object?
Other than hacking the underlying C code, no. Garbage collection is managed by the runtime so you don't have to worry about it. Here is a decent reference on the algorithm in Ruby 2.0.
Once you have no more references to the object in memory, the garbage collector will go to work. You should be fine.
How do I destroy a child object if I set the relation to nil and save?
First
The
dependent: :destroy
will only delete/destroy the dependency when
the parent record is destroy. you should use this to get rid of orphan
records.
This is how I would do something like this.
class User < ApplicationRecord
belongs_to :image, optional: true, dependent: :destroy
before_save :check_images, :only => [:update]
...
private
def check_images
if image_id.nil? && image_id_changed?
Image.find(image_id_was).destroy
end
end
end
I hope that this can help you and put you in the right tack
How do you delete an ActiveRecord object?
It's destroy
and destroy_all
methods, like
user.destroy
User.find(15).destroy
User.destroy(15)
User.where(age: 20).destroy_all
User.destroy_all(age: 20)
Alternatively you can use delete
and delete_all
which won't enforce :before_destroy
and :after_destroy
callbacks or any dependent association options.
User.delete_all(condition: 'value')
will allow you to delete records
without a primary key
Note: from @hammady's comment, user.destroy
won't work if User model has no primary key.
Note 2: From @pavel-chuchuva's comment, destroy_all
with conditions and delete_all
with conditions has been deprecated in Rails 5.1 - see guides.rubyonrails.org/5_1_release_notes.html
Rails - destroy associations from object with condition
Just remove @foo.bars.each{|b| b.update_attribute(:blub_id, nil)}
and make another try. I supposed that blub_id
is a foreign key that indicates to which foo the current bar belongs to.
When you make the blub_id
is equal to null, the records with a blub_id
null is belongs to nothing and then @foo.bars.where(type: "test").destroy_all
doesn't include these bars.
How to properly destroy a class
The Ruby idiom for this is to yield to a block which does work, and when the block returns, do cleanup. Ruby's built-in "File.open" does this:
File.open("/tmp/foo") do |file|
file.puts "foo"
end
When the block ends, the file is closed for you, without you having to do anything. This is an excellent idiom. Here's how you might implement something like that:
class Foo
def self.open(*args)
foo = new(*args)
yield foo
foo.close
end
def initialize
# do setup here
end
def close
# do teardown here
end
end
And to use it:
Foo.open do |foo|
# use foo
end
Foo#close
will be caused automatically after the end
This will work with subclassing as well. That's because class methods are inherited just as are instance methods. Here's the superclass:
class Superclass
def self.open(*args)
o = new(*args)
yield o
o.close
end
def initialize
# common setup behavior
end
def close
# common cleanup behavior
end
end
and two derived classes:
class Foo < Superclass
def initialize
super
# do subclass specific setup here
end
def close
super
# do subclass specific teardown here
end
end
class Bar < Superclass
def initialize
super
# do subclass specific setup here
end
def close
super
# do subclass specific teardown here
end
end
to use:
Foo.open do |foo|
# use foo
end
Bar.open do |bar|
# use bar
end
If you really need to make sure that cleanup happens no matter what, then use an ensure clause in the class method:
def self.open(*args)
foo = new(*args)
begin
yield foo
ensure
foo.close
end
end
This way, cleanup happens even if there is an exception in the block.
Is there a way destroy an object based on a date attribute as opposed to created_at in Ruby on Rails?
I ended up using the whenever gem and was able to make a rake task that runs every 2 minutes checking the database for events who's end_date
is less than Time.now - 12.hours
. Any that meet this criteria are removed from the database. I ran into some issues but this thread was extremely helpful.
Following the steps I ended up writing a schedule.rb in my config directory which housed the rake task. In my schedule.rb file:
set :environment, "development"
set :output, {:error => "log/cron_error_log.log", :standard => "log/cron_log.log"}
every 2.minutes do
rake "events:delete_12_hours_old"
end
In lib/tasks/events.rake file:
namespace :events do
desc "Delete event after 12 hours from date"
task delete_12_hours_old: :environment do
Event.where('end_date <= ?', Time.now-12.hours).destroy_all
end
end
Thank you guys for all of the help and advice!
RoR - Don't destroy object, just flag as hidden
Something like this:
class Point < ActiveRecord::Base
def archive
update_attribute!(:displayed, false)
end
end
And then call @point.archive
in the destroy action of your controller where you would normally call @point.destroy
. You can also create a default_scope
to hide archived points until you explicitly query for them, seethe RoR guide on appling a default scope.
Edit: Updated my answer as per normalocity & logan's comments below.
Destroy associated object from rails console
You should be able to do something like
a.related_products.destroy_all
This will destroy
ALL of the related products in the list.
Product.destroy_all(related_products: nil)
This will loop over all products and look to see if the related_products
field is empty.
You may also want to setup dependent destroys. Something like
class MyModel < ActiveRecord::Base
has_many :related_products, dependent: :destroy
end
Related Topics
In Rails - Is There a Rails Method to Convert Newlines to <Br>
How to Compare Strings Ignoring the Case
Put a Link in a Flash[:Notice]
Differencebetween Link_To, Redirect_To, and Render
Node.Js Not Found by Rails/Execjs
How to Map/Collect with Index in Ruby
How to Check If a Given Directory Exists in Ruby
Checking If a Variable Is an Integer
How to Get the Current Time as 13-Digit Integer in Ruby
How to Print Out the Contents of an Object in Rails for Easy Debugging
Using a String as a Variable at Run Time
Rails - Sort by Join Table Data
How to Prevent Nokogiri from Adding <Doctype> Tags
How to Dynamically Create a Local Variable in Ruby
Generate a Powerset of a Set Without Keeping a Stack in Erlang or Ruby