2012-09-17 16 views
17

ho controllando opzioni di belongs_to metodo e sulla verifica seguenti comportamenti in Rails 3.2.7: dipendente =>: eliminare il belongs_to non elimina oggetto proprietario

Come per link qui sopra l'opzione :dependent afferma che

Se impostato su: destroy, l'oggetto associato viene distrutto quando si trova questo oggetto . Se impostato su: delete, l'oggetto associato viene cancellato senza chiamando il suo metodo destroy.

quanto ho capito l'autore dovrebbe essere rimosso se post viene rimosso in caso seguente:

class Post < ActiveRecord::Base 
    belongs_to :author, :dependent => :delete 
end 

class Author < ActiveRecord::Base 
    attr_accessible :name 
    has_one :post 

    before_destroy :log_author_removal 

    private 
    def log_author_removal 
     logger.error('Author is getting removed') 
    end 

end 

In console:

> Post.first 
    Post Load (0.4ms) SELECT "posts".* FROM "posts" LIMIT 1 
=> #<Post id: 5, title: "Post 5", author_id: 3> 
> p.delete 
    SQL (197.7ms) DELETE FROM "posts" WHERE "posts"."id" = 5 
=> #<Post id: 5, title: "Post 5", author_id: 3> 
> Author.find(3) 
    Author Load (0.5ms) SELECT "authors".* FROM "authors" WHERE "authors"."id" = ? LIMIT 1 [["id", 3]] 
=> #<Author id: 3, name: "Author 3"> 

Tuttavia chiamando p.destroy cancella autore associato.

Sono stato frainteso sopra la dichiarazione citata?

risposta

24

Sì, chiamando delete in genere salta tutte le richiamate che sia voi che le rotaie impostate per distruggere il record. Questi includono i callback come before_destroy e anche la distruzione dei record associati.

Pertanto, se si chiama p.delete non farà nulla con i record associati.

Quando si chiama p.destroy lo farà:

  1. chiamata la before_destroy richiamata, se impostato.
  2. Elimina l'oggetto.
  3. Se si imposta :dependent => :delete, verrà semplicemente eliminato l'oggetto Autore. Se lo si imposta su :destroy, l'intero processo verrà ripetuto per l'oggetto autore (callback & che distrugge i record correlati, se applicabile).
  4. Chiamare la richiamata after_destroy se impostata.
+0

Grazie Jakub. Come al punto 3, l'oggetto autore dovrebbe essere cancellato, ma in realtà non lo è. Ecco perché ho postato qui per ottenere input dalla community –

+0

@AmitPatel Sì ma non hai chiamato 'destroy', hai chiamato' delete'. –

+0

Ciò significa che 'delete' non avrebbe alcun impatto sull'oggetto associato, indipendentemente da cosa è impostato per': dependent'. –

1
belongs_to :author, :dependent => :delete 

dovrebbe essere: belongs_to: autore,: dipendente =>: distruggere

: distruggere e: delete si comportano in modo diverso in ActiveRecord, eliminare bypassa convalide e le associazioni di AR, in tal modo gli oggetti associati non sono stati rimossi.

+0

Se si utilizza eliminare o distruggere è una cosa diversa. Voglio solo capire se il record associato deve essere cancellato o non come da istruzione _Se impostato su: delete, l'oggetto associato viene cancellato senza chiamare il suo metodo destroy_ –

-1

associazione belongs_to non può sostenere il : eliminare per : missione che dipendono. Supporta solo : distruggi. Si prega di fare riferimento a questo link .

+0

Non riesco a trovare nulla che afferma appartiene_per l'associazione non può supportare: delete per: dependent. –

7

Da quello che ho capito:

:dependent => :destroy attiveranno association.destroy se si chiama destroy sull'oggetto.

:dependent => :delete attiverà association.delete se si chiama destroy sull'oggetto.

In entrambi i casi, è necessario chiamare destroy sull'oggetto padre. La differenza sta nel methos che viene chiamato sull'oggetto figlio. Se non si desidera attivare i filtri di distruzione sull'oggetto figlio, utilizzare :dependent => :delete. Se li vuoi, usa :dependent => :destroy.

Prendendo rapidamente un'occhiata alla fonte qui: https://github.com/rails/rails/blob/357e288f4470f484ecd500954fd17fba2512c416/activerecord/lib/active_record/associations/builder/belongs_to.rb#L68

Vediamo che chiamando dipendente sarà solo creare un after_destroy sul modello di genitore, chiamando sia delete o destroy sull'oggetto figlio. Ma in entrambi i casi, crea un after_destroy.

+0

Grazie. La tua risposta sembra più pulita. –

2

sostegno dell'associazione belongs_to sia : eliminare e : distruggere per : dipendente. è possibile fare riferimento al di sotto di collegamento http://apidock.com/rails/v4.0.2/ActiveRecord/Associations/ClassMethods/belongs_to

chiamando cancellare salta tutte le richiamate come before_destroy e così non eliminare i record associati per oggetto l'associazione pure.

Esempio

class Order < ActiveRecord::Base 
has_one :project, :dependent => :delete 
has_many :resources, :dependent => :delete 
end 

class Project < ActiveRecord::Base 
belongs_to :order, :dependent => :delete 
end 

Nel codice di cui sopra, se il progetto è stato distrutto allora ordine sarà così eliminato, ma le risorse al fine di non cancellerà ma se usiamo

belongs_to :order, :dependent => :destroy 

poi risorse allegato anche con gli ordini cancellati sul progetto destroy.

Problemi correlati