2015-10-29 12 views
6

Ich habe 2 Rails Modelle: Buch und Kategorie, wo ein Buch belongs_to eine Kategorie, eine Kategorie has_many Bücher.Fehlende Touch-Option in Rails has_many Beziehung

Der Kategoriename wird auf jeder Buchseite angezeigt, und Seiten werden zwischengespeichert.

Wenn ich einen Kategorienamen ändere (zB von "Sci Fi" zu "Science Fiction"), dann werden alle entsprechenden Buchseiten veraltet sein, und Bücher müssen "berührt" werden, um HTML-Regeneration auszulösen.

Es scheint Sinn machen zu können, tun:

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

Aber the option is unavailable, ich denke, da der touch Mechanismus jedes Objekt instanziiert würde, die für has_many Beziehungen in einer großen Leistungseinbußen führen könnte.

dass zu vermeiden, ich bin mit rohen SQL wie folgt:

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 

die ziemlich schrecklich. Gibt es einen besseren Weg?

Antwort

5

Sie können nicht touch auf has_many Zuordnung verwenden, funktioniert es nur mit belongs_to, das ist eine Tatsache.

Wenn ich richtig verstehe, was Sie wollen, werden die Antworten mit touch:true im Book-Modell nicht funktionieren, da das Book-Objekt nicht aktualisiert wird, wenn Sie das Kategorie-Modell ändern und die Ansicht nicht regeneriert.

Also ich denke, Ihre Lösung ist das Beste dafür. (Sie können auch books.update_all(updated_at: Time.now) verwenden)

+1

Sie sind in beiden Punkten richtig: 1) Ich muss alle Bücher ändern, wenn eine Kategorie ändert; 2) update_all ist einfacher und instanziiert die Modelle NICHT; Die direkt an die Datenbank gesendete SQL-Abfrage vermeidet Leistungsprobleme. – Giuseppe

+0

aber wird dies ein Cache-Update auslösen? – user1262904

0

Es gibt tatsächlich eine Touch-Option für Relationen in ActiveRecord. Der einzige Unterschied mit der Syntax Ihres erwarten ist, dass es eine Option für belongs_to ist:

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

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

+1

Zunächst sollte es durch Konvention "Kategorie" (Singular) sein. Was das tun wird, ist die Kategorie zu aktualisieren, wenn ein Buch erstellt/geändert wird, was eine Art Gegenteil von dem ist, was ich brauche, d. H. Alle Kinder berühren, wenn sich der Elternteil ändert. – Giuseppe

0

Es ist nur auf der belongs_to Methode, die in Ihren Büchern Modell sein sollte. So können Sie es immer noch benutzen.

+0

Lol, zur gleichen Zeit beantwortet, hat die andere Antwort viel bessere Erklärung :). –

+0

Danke Freund: p – Caillou

Verwandte Themen