2015-10-29 6 views
6

Ho 2 modelli di Rails: Libro e Categoria, dove un libro belongs_to una categoria, una categoria has_many libri.L'opzione di tocco mancante in Rails ha_molto rapporto

Il nome della categoria viene visualizzato nella pagina di ogni libro e le pagine sono memorizzate nella cache.

Se cambio il nome di una categoria (ad esempio, da "Sci Fi" a "Fantascienza"), tutte le pagine del libro corrispondenti saranno obsolete ei libri devono essere "toccati" per attivare la rigenerazione HTML.

Sembrerebbe di dare un senso di essere in grado di fare:

class Category << ActiveRecord::Base 
    has_many :books, touch: true 
end 

Ma the option is unavailable, credo perché il meccanismo touch sarebbe un'istanza di ogni oggetto, che potrebbe tradursi in un importante calo di prestazioni per has_many relazioni.

Per evitare questo, sto usando SQL prime come segue:

class Category << ActiveRecord::Base 
    has_many :books 
    after_update -> { 
    ActiveRecord::Base.connection.execute "UPDATE books SET updated_at='#{current_time_string}' WHERE category_id=#{id})" 
    } 
end 

che è abbastanza terribile. C'è un modo migliore?

risposta

5

Non è possibile utilizzare l'associazione touch su has_many, funziona solo con belongs_to, questo è un dato di fatto.

Se ho capito correttamente ciò che si desidera, le risposte con touch:true nel modello Book non funzioneranno, perché l'oggetto Libro non verrà aggiornato quando si modifica il modello di categoria e la vista non verrà rigenerata.

Quindi penso che la soluzione sia la migliore. (È possibile utilizzare anche books.update_all(updated_at: Time.now))

+1

Hai ragione su entrambi i fronti: 1) Devo cambiare tutti i libri quando una categoria cambia; 2) update_all è più semplice e NON istanzia i modelli; la query SQL inviata direttamente al DB evita problemi di prestazioni. – Giuseppe

+0

ma questo farà scattare un aggiornamento della cache? – user1262904

0

Esiste effettivamente un'opzione di tocco per le relazioni in ActiveRecord. L'unica differenza con la sintassi vostro previsto è che si tratta di un'opzione per belongs_to:

class Book << ActiveRecord::Base 
    belongs_to :categories, touch: true 
end 

Documentazione: http://apidock.com/rails/ActiveRecord/Persistence/touch

+1

Innanzitutto, per convenzione dovrebbe essere 'categoria' (singolare). Quello che farà è aggiornare la categoria quando un libro viene creato/modificato, che è il contrario di ciò di cui ho bisogno, cioè tocca tutti i bambini quando il genitore cambia. – Giuseppe

0

E 'disponibile solo sul metodo belongs_to che dovrebbe essere nel modello libri. Quindi puoi ancora usarlo.

+0

Lol, ha risposto allo stesso tempo, l'altra risposta ha una spiegazione molto migliore :). –

+0

Grazie amico: p – Caillou

Problemi correlati