Is there a a way to destroy Rails model without calling callbacks for dependent: :destroy
in associations.
example:
class Administration < ActiveRecord::Base
include IdentityCache
attr_accessible :auto_sync, :response_rate_calc_state, :description,
:year, :project_id, :season, :auto_async, :synchronized_at
has_many :report_distributions
has_many :rosters, dependent: :destroy
before_destroy :delete_file
attr_accessible :file
has_attached_file :file,
path: ":class/:id_partition/:basename.:extension",
storage: :s3,
bucket: S3Config::AWS_BUCKET_MODELS,
s3_credentials: {
access_key_id: S3Config::AWS_ACCESS_KEY_ID_MODELS,
secret_access_key: S3Config::AWS_SECRET_ACCESS_KEY_MODELS
},
s3_permissions: 'authenticated-read',
s3_protocol: 'https',
s3_storage_class: :reduced_redundancy
def authenticated_url(style = nil, expires_in = 10.seconds)
file.s3_object(style).url_for(:read, secure: true, expires: expires_in).to_s
end
def delete_file
file.s3_object(nil).delete if self.file?
end
# ...
So when I call
Administration.find(id).destroy
I want to just delete record and attachment file, but DO NOT call callbacks for deleting rosters
has_many :rosters, dependent: :destroy
--
PS I don't want to disable has_many :rosters, dependent: :destroy
. I just need to temporary disable callback.
Rails Delete operation using delete method Unlike the destroy method, with delete, you can remove a record directly from the database. Any dependencies to other records in the model are not taken into account. The method delete only deletes that one row in the database and nothing else.
dependent: :destroy Rails, when attempting to destroy an instance of the Parent, will also iteratively go through each child of the parent calling destroy on the child. The benefit of this is that any callbacks and validation on those children are given their day in the sun.
Dependent is an option of Rails collection association declaration to cascade the delete action. The :destroy is to cause the associated object to also be destroyed when its owner is destroyed.
You can keep your association as it is and skip the callback one of the following ways:
1. Using delete
instead of destroy since it won't fire callbacks
Administration.find(id).delete
2. Use skip_callback
method (found it in this blog post):
Administration.skip_callback(:destroy, :bofore, :action_you_need_to_disable)
#then safely destroy without firing the action_you_need_to_disable callback
Administration.find(id).destroy
3. Or even better, if you already know when you need to skip the callback, you could do:
class Admistration < ActiveRecord::Base
has_many :rosters, dependent: :destroy
skip_callback :destroy, :before, :action_you_need_to_disable, if: -> { #conditions }
end
Link: api docs on skip_callback
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