Frage

I Einzel-Table Vererbung (STI) für eine Rails App auf einem meiner Modelle verwenden und ich Probleme speichern Modellobjekte auf einer Konstante. Ich habe das Problem in einem Beispielprojekt isoliert und legte sie GitHub: http://github.com / fcoury / Schienen-sti-Caching

Was ich versuche, eine Modellinstanz zu tun wird geladen (in diesem Fall ein Musik-Modell, das von dem Medienmodell über STI erbt) auf einem Initialisierer (in Rails' /config/initializers/ Verzeichnis) und halten Sie sie auf einem konstanten:

MUSIC_CACHE = Hash.new
Music.all.each { |m| MUSIC_CACHE[m.id] = m }

Und ich habe eine Probe-Controller, macht folgendes:

class MusicsController < ApplicationController
  def index
    require 'pp'
    pp MUSIC_CACHE
    @debug = []
    MUSIC_CACHE.each_pair do |k, v|
      music = Music.find(k)
      d "Object for Music.find(#{k})  => class: #{music.class} - class obj_id: #{music.class.object_id} - #{music.inspect}"
      d "Object for MUSIC_CACHE[#{k}] => class: #{v.class} - class obj_id: #{v.class.object_id} - #{v.inspect}"

      begin
        d "  - Music.is_a?(Media) => #{v.is_a?(Media)}"
        d "  - Try to call name   => #{v.name}"
      rescue
        d "*** Error raised:\n#{$!}"
      end
    end

    @musics = Music.all
  end

  def d(s)
    puts s
    @debug << s
  end
end

Und eine Ansicht, mit ihm zu gehen:

<h1 id="music">Music</h1>

<ul>
  <% for m in @musics %>
  <li><%= m.name %> - <%= m.file %></li>
  <% end %>
</ul>

<pre><%=h @debug.join("\n") %></pre>

Das erste Mal, dieser Code ausgeführt wird, ist die Ausgabe auf dem <pre> Tag folgt aus:

  Object for Music.find(2)  => class: Music - class obj_id: 13067420 - #<Music id: 2, name: "5th Symphony", file: "5s.mp3", type: "Music", created_at: "2009-05-06 16:31:41", updated_at: "2009-05-06 16:31:41">
  Object for MUSIC_CACHE[2] => class: Music - class obj_id: 13067420 - #<Music id: 2, name: "5th Symphony", file: "5s.mp3", type: "Music", created_at: "2009-05-06 16:31:41", updated_at: "2009-05-06 16:31:41">
    - Music.is_a?(Media) => true
    - Try to call name   => 5th Symphony

Allerdings, wenn ich nur die Seite neu zu laden, hier ist was ausgegeben wird:

Object for Music.find(2)  => class: Music - class obj_id: 18452280 - #<Music id: 2, name: "5th Symphony", file: "5s.mp3", type: "Music", created_at: "2009-05-06 16:31:41", updated_at: "2009-05-06 16:31:41">
Object for MUSIC_CACHE[2] => class: Music - class obj_id: 13067420 - #<Music id: 2, name: "5th Symphony", file: "5s.mp3", type: "Music", created_at: "2009-05-06 16:31:41", updated_at: "2009-05-06 16:31:41">
  - Music.is_a?(Media) => false
*** Error raised:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.include?

Kennt jemand die Gründe für diesen Fehler?

War es hilfreich?

Lösung

Meine erste Idee wäre, dass Rails freigibt (Ungültigmachungseinträge) alle Modellobjekte nach einer Anforderung dient. So wird class: Music - class obj_id: 13067420 unbrauchbar in der zweiten Anfrage. Ich würde vorschlagen, einen Blick auf die Active Quellcode hat und herauszufinden, wer Modellobjekte entkräftet.

Auch diese Schienen Modell Caching Tutorial können nützlich sein: http: / /railscasts.com/episodes/115-caching-in-rails-2-1

Andere Tipps

Im Grunde kann man nicht darauf.

In Entwicklungsumgebung, mit jeder Anforderung werden die Klassen neu geladen. Das heißt, sie sind völlig zerstört und neu erstellt. Das ursprüngliche Klassenobjekt ist weg, ein neuer an seine Stelle tritt.

Wenn Sie ein Objekt über Anfragen zu halten, in der zweiten Anforderung von der ursprünglichen Klasse des Objekt noch erben, die eine, die entfernt wurde. Die Konstante, die zu dieser Klasse darauf verweist nun auf ein neues Klasse-Objekt, das nicht auf die vorherigen je nach identisch ist oder nicht, ob Sie die Klassendefinition oder Plugins geändert, die es beeinflussen, aber es wird noch eine andere Klassenobjekt sein in Speicher und das alte Objekt nicht wissen, dass es aus diesem neuen Klasse Objekt erben sollte.

Ich gehe davon aus, wenn Sie Ihre Anwendung in der Produktionsumgebung ausführen, es wird funktionieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top