Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to destroy Rails model without calling dependent: :destroy on associations

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.

like image 225
nothing-special-here Avatar asked Apr 30 '14 09:04

nothing-special-here


People also ask

What is the difference between delete and destroy in Rails?

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.

Why use dependent destroy in Rails?

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.

What does dependent destroy mean?

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.


1 Answers

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

like image 105
Nimir Avatar answered Sep 24 '22 07:09

Nimir