Notification of object destruction in Ruby
If you need to control what happens when an object is destroyed, you really should be explicitly destroying it yourself - this is by design. You're not supposed to be able to destroy an object explicitly either - this is also by design.
In other words, from the perspective of your program, an object is never destroyed or destroyable. For these reasons you should re-think the problem (this is not an uncommon need - release of resources when the object is no longer needed) so it fits into the Ruby paradigm.
Setting the object to nil gives a hint to the garbage collector, but does not necessarily immediately destroy it.
However, if you must have the garbage collector handle it, then read on.
There is no direct support for a destructor, but you can have it call a finalizer function when it is destroyed.
According to http://pleac.sourceforge.net/pleac_ruby/classesetc.html it may not be garbage collected if it contains a reference to the original object, so must be a class method and not an instance method.
class MyClass
def initialize
ObjectSpace.define_finalizer(self,
self.class.method(:finalize).to_proc)
end
def MyClass.finalize(id)
puts "Object #{id} dying at #{Time.new}"
end
end
Ruby: Destructors?
You can use ObjectSpace.define_finalizer
when you create the image file, and it will get invoked when the garbage man comes to collect. Just be careful not to reference the object itself in your proc, otherwise it won't be collected by the garbage man. (Won't pick up something that's alive and kicking)
class MyObject
def generate_image
image = ImageMagick.do_some_magick
ObjectSpace.define_finalizer(self, proc { image.self_destruct! })
end
end
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.
ruby equivalent of destructor
There is a hook called ObjectSpace.define_finalizer that is called when an object is destroyed.
Is there a way to destroy *self* after a class is instantiated?
Ruby Finalizers Aren't Really Destructors
While you can define finalizers for Ruby objects, they aren't really destructors as such. In fact, they aren't triggered until after the object is destroyed. The docs say:
define_finalizer(obj, aProc=proc())
Adds aProc as a finalizer, to be called after obj was destroyed.
Rethink Your Approach
Rather than instantiating your browser instance with #new, consider a pattern more like:
class Something
attr_accessor :browser
def start_browser
end
def quit_browser
end
end
s = Something.new
s.start_browser
s.quit_browser
Other patterns are also possible, including setting callbacks or timers within your object. Ultimately, the point is that objects should go out of scope and be garbage collected---they can't actually destroy themselves.
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.
Check if ActiveRecord object is destroyed using the .destroy() return value
If you're unsure, you can use destroyed?
method. Return value of destroy is undocumented, but it returns just freezed destroyed object (you cannot update it). It doesn't return status of destroy action.
Although generally destroying object should always succeed, you can listen for ActiveRecordError. For example Optimistic Locking can raise ActiveRecord::StaleObjectError on record destroy.
Send async email about destroyed objects
When deleting an object and sending an email is such tightly coupled, you can create a sidekiq job which does both things. So you have only to send an id to the job. The sidekiq job deletes your object and sends the email synchronous, within the job. For your request the mail is still send asynchron.
`marked_for_destruction?' for false:FalseClass
If I understand well your notification system, you try to send a notif to admins every time a Leave
is created.
Assuming that, your error comes from your recipients
method:[user.admin]
returns [true]
or [false]
and when you iterate on it, you do: Notification.create(recipient: true/false, ...)
You can fix your system by creating a user scope for admins:
class User < ApplicationRecord
#...
scope :admins, -> { where(admin: true) }
end
and change the recipients
method like:
class Leave < ApplicationRecord
#...
private
def recipients
User.admins
end
def create_notifications
#...
end
end
Related Topics
Why Can't I Use an Integer as a Key Using the New Ruby 1.9.2 Hash Syntax
How Does Require Rubygems Help Find Rubygem Files
What Does &: Mean in Ruby, Is It a Block Mixed with a Symbol
How to Improve Jruby Load Time
Why Does Array.Each Behavior Depend on Array.New Syntax
New Rails Project: 'Bundle Install' Can't Install Rails in Gemfile
Windows: Rails: Error Installing Bson_Ext
Bundle Install Issue with Libv8 and Rails
Building Ruby with Rbenv and Ruby-Build Fails with Undefined Symbol: Sslv2_Method
Sass::Syntaxerror: File to Import Not Found or Unreadable: Compass in Production
Using $ Sudo Bundle Exec ... Raises 'Bundle: Command Not Found' Error
How to Create Symbol (Hash Key) from Association, Using New Ruby (1.9) Hash Syntax