Frage

Ich arbeite an einer Rails-Anwendung, wo ich das Seite-Caching bin mit statischer HTML-Ausgabe zu speichern. Das Caching funktioniert gut. Ich habe Probleme, die Caches abläuft, though.

Ich glaube, mein Problem ist, zum Teil, weil ich den Cache nicht von meinem Controller bin ablaufen. Alle Aktionen für diese notwendig werden innerhalb des Modells behandelt. Dies scheint, wie es machbar sein sollte, aber alle Verweise auf modellbasierten Cache-Ablauf, die ich scheinen zu finden bin veraltet zu sein oder sind sonst nicht funktioniert.

In meiner environment.rb Datei, ich rufe

config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )

Und ich habe, in dem / Kehrmaschinen Ordner, eine LinkSweeper-Datei:

class LinkSweeper < ActionController::Caching::Sweeper
  observe Link

  def after_update(link)
    clear_links_cache(link)
  end

  def clear_links_cache(link)
  # expire_page :controller => 'links', :action => 'show', :md5 => link.md5
    expire_page '/l/'+ link.md5 + '.html'
  end
end

So ... Warum ist es nicht die Cache-Seite zu löschen, wenn ich das Modell aktualisieren (Prozess: mit Skript / Konsole, ich Elemente aus der Datenbank auswählen und Speicher sie, aber ihre entsprechenden Seiten löschen nicht aus dem Cache), und ich bin auch die spezifische Methode im Link-Modell aufrufen, die die Kehrmaschine normalerweise aufrufen würde. Weder funktioniert.

Wenn es darauf ankommt, die Cache-Datei ist ein MD5-Hash ein Schlüsselwert in der Links-Tabelle ab. Die Cache-Seite wird als so etwas wie / l gespeichert zu werden / 45ed4aade64d427 ... 99919cba2bd90f.html.

Im Wesentlichen scheint es, als ob die Kehrmaschine nicht tatsächlich den Link zu beobachten. Ich habe auch gelesen ( hier ), dass es vielleicht möglich, die Kehrmaschine zu config.active_record.observers in environment.rb einfach hinzufügen, aber das schien nicht, es zu tun (und ich, wenn die LOAD_PATH von app / Kehrmaschinen in environment.rb nicht sicher war, vermieden, dass).

War es hilfreich?

Lösung

Nur ein Hinweis:. Sie cache_sweeper in Application verwenden

class ApplicationController < ActionController::Base
  cache_sweeper :my_sweeper
end

class MySweeper < ActionController::Caching::Sweeper
  observe MyModel

  def after_update(my_model)
    expire_page(...)
  end
end

Andere Tipps

So habe ich eine Reihe verschiedenen Ansätze versucht, um zu sehen, was funktioniert und was nicht.

Auch die Situation zusammenfassen: Mein Ziel ist es im Cache gespeicherten Seiten verfallen, wenn ein Objekt Updates, aber sie auslaufen, ohne auf einer Controller-Aktion unter Berufung Konventionelle Kehrmaschinen eine Linie in der Steuerung verwenden zu benachrichtigen. die Kehrmaschine, die es braucht um zu funktionieren. In diesem Fall kann ich keine Zeile in der Steuerung verwenden, da das Update innerhalb des Modells geschieht. Normale Kehrmaschine Tutorials funktioniert nicht, da sie, dass Ihre Haupt Interaktion mit dem Datenbankobjekt anmaßen über den Controller ist.

Wenn dies lesen, Sie sehen, wie man meinen Code verschärfen, bitte kommentieren und lassen Sie mich wissen.

Lassen Sie uns zunächst auf die Dinge betrachten, die Arbeit zu tun, falls Sie auf diese stecken, auch, und Hilfe benötigen.

Von allen Dingen, die ich versuchte, das einzige, was wirklich an die Arbeit schien, war ein after_update Befehl im Observer für das Modell zu erklären. In diesem Befehl verwenden ich den expliziten Befehl für die expire_page Aktion, und enthalten einen Pfad, der in routes.rb erklärt worden ist.

So. Dies funktioniert:

config / routes.rb:

map.link 'l/:md5.:format',  :controller => 'links', :action => 'show'

In app / models / link_observer.rb:

def after_update(link)
  ActionController::Base.expire_page(app.link_path(:md5 => link.md5))
end
Hinweis

, dass „md5“ ist spezifisch für meine Anwendung. Vielleicht haben Sie verwenden möchten. ID oder eine andere eindeutige Kennung

Ich fand auch, dass er erklärt, dass Action :: Base ... Zeile aus dem Verfahren in dem Modell, das die Aktualisierung gearbeitet tut. Das heißt, innerhalb Link.rb, die in dem Verfahren, das tatsächlich ist die Aktualisierung der Datenbank, wenn ich stecken gerade das ganze Linie in, es funktionierte. Aber da ich möchte vielleicht die Seite Cache auf anderen Methoden in der Zukunft auslaufen, würde ich eher in die Observer extrahiert haben.

Lassen Sie uns nun auf einige Dinge suchen, die NICHT, Sie googeln um für diese im Falle nicht funktioniert.

Calling "expire_page (...)" im after_update (Link) Methode innerhalb link_observer.rb nicht funktionierte, da es eine "nicht definierte Methode` expire_page '" zurückgegeben Fehler

Erstellen einer Sweeper Datei , dass das Modell beobachtet hat nicht funktioniert. Ich konnte keinen Fehlercodes finden, aber es schien einfach nicht einmal bewusst zu sein, dass es einen Job zu tun hatte. Das war, nachdem ausdrücklich "config.load_paths + =% W (# {RAILS_ROOT} / app / Kehrmaschinen)" innerhalb environment.rb aufrufen. Für den Fall, ich Fett-Finger etwas in diesem Code, hier ist es:

class LinkSweeper < ActionController::Caching::Sweeper
  observe Link

  def after_update(link)
    clear_links_cache(link)
  end

  def clear_links_cache(link)
    # DID NOT WORK    expire_page :controller => 'links', :action => 'show', :md5 => link.md5
    # DID NOT WORK    expire_page '/l/'+ link.md5 + '.html'
    # DID NOT WORK    ActionController::Base.expire_page(app.link_path(:md5 => link.md5))
  end
end

Das obige Beispiel die link_sweeper.rb Datei in einem Verzeichnis hatte, / app / Kehrmaschinen. Ich habe auch versucht im app / model Verzeichnis setzen link_sweeper.rb, und versuchte, sie mit dem config.active_record.observers Befehl in environment.rb Aufruf:

config.active_record.observers = :link_observer, :link_sweeper

Aber das hat nicht funktioniert, auch nicht.

Also, ja. Es ist durchaus möglich, dass eine dieser Methoden funktionieren würde, und dass ich messed etwas im Code auf. Aber ich glaube, ich habe alles durch das Buch.

Letztlich zusammenzufassen: Anstatt eine Kehrmaschine mit Seiten-Caching abläuft, möchten Sie einen after_ Rückruf in das Modell des Observer einzurichten. Sie werden den expliziten Pfad zur Base.expire_page Methode verwenden möchten:

def after_update(<model>) # where <model> is the name of the model you're observing
  ActionController::Base.expire_page(app.<model>_path(:id => <model>.id)) # where <model> is the name of the model you're observing
end

Hoffentlich wird jemand anderes auf dem Weg helfen. Noch einmal, wenn Sie irgendwo in meinem nicht-funktionierenden Code sehen, wo ich etwas anders gemacht haben sollte, lassen Sie es mich wissen. Wenn Sie etwas in meinem Arbeits Code zu sehen, die straffer sein können, lassen Sie es mich wissen, dass auch.

ich erleben das gleiche Problem bei dem Versuch, Fragment-Caching (Schienen 3) zu tun. Kann die Kehrmaschine bekommen zu beobachten, so entschied ich mich für die Lösung es einen AR-Beobachter zu machen, wie oben und rufe ApplicationController.new.expire_fragment(...) beschrieben.

Ich habe diese Arbeit bekommen. Der einzige kleine Unterschied in meinem Setup ist, dass die Kehrmaschine Teil einer Rails-Engine ist; welche Konten für geringe Unterschiede (Laden der Kehrmaschine Datei mit einem erfordern im Motor init, anstatt sie auf die Laststrecke in environment.rb Zugabe, etc).

So ist die Kehrmaschine in der init.rb des Motors wie folgt geladen:

require File.join(File.dirname(__FILE__), 'app', 'sweepers', cached_category_count_sweeper')

Ich nannte es eine Kehrmaschine, weil es „Sweeps“ die Cache, aber ich denke, es ist nur ein Beobachter auf dem Modell:

class CachedCategoryCountSweeper < ActiveRecord::Observer
  observe CategoryFeature

  def before_save(cf)
    expire_cache(cf.category_id_was) if cf.category_id_changed?
  end

  def after_save(cf)
    expire_cache(cf.category_id)
  end

  def after_destroy(cf)
    expire_cache(cf.category_id)
  end

  def expire_cache(c)
    ApplicationController.expire_page("/categories/#{c}/counts.xml") if !c.nil?
  end
end

Ehrlich gesagt, ich weiß nicht, wie der Weg zum Festcode, aber ich versuchte, füge hinzu:

include ActionController:UrlWriter

und dann unter Verwendung der Pfad-Methode, aber es funktioniert nur für mich in der Entwicklung. Es dauerte nicht in der Produktion arbeiten, weil meine Produktionsserver eine relative URL Wurzel (anstelle von virtuellen Hosts) und die interne Methode „page_cache_path“ konsequent den falschen Dateipfad bekommen würde verwendet, damit es nicht ablaufen kann.

Da es sich um einen Beobachter, ich zum environment.rb hinzugefügt:

config.active_record.observers = :cached_category_count_sweeper

Schließlich wird die Steuerung, die den Cache verwendet (es nicht verfallen, dass durch das Modell Beobachter getan wird):

class CachedCategoryCountsController < ApplicationController
  caches_page :index

  # GET /cached_category_counts.xml
  def index
    ...
  end
end

Wie auch immer, hoffen, das hilft.

Andres Montano

Ich habe in der Lage gewesen, um es von dem Weg zur Arbeit, der Zugabe

ActionController::Base.expire_page(app.link_path(:md5 => @link.md5))

auf das Verfahren in dem Modell selbst, der die Datenbank ist zu aktualisieren. Das fühlt sich ein wenig hacky, aber, und ich würde gerne wissen, ob jemand erklären kann, warum es nicht mit der normalen Kehrmaschine Setup zu arbeiten, und wenn es eine elegantere Art und Weise zu handhaben.

Das Code-Snippet (abgesehen von Anpassungen ich für meine eigene app setzte in) kam von dieser Beitrag auf ruby-forum.com .

ich ein wenig über dieses Thema schrieb hier: Rails Cache Sweeper Verwirrung . Würde gerne Ihre Meinung hören.

Basierend auf @moiristo und @ZoogieZork ‚s Antworten, ich vermute, dass dies funktionieren würde (nicht getestet).

class LinkSweeper < ActiveRecord::Observer
  include ActionController::Caching::Pages
  # or if you want to expire fragments
  #include ActionController::Caching::Fragments

  observe Link

  def after_update(link)
    expire_page( ... )
    #expire_fragment( ... )
  end
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top