Frage

Ich bin ein wenig verwirrt, die Mechanik der eager loading in aktiven Datensatz. Sagen wir ein Book Modell viele Pages und ich holen ein Buch mit dieser Abfrage hat:

@book = Book.find book_id, :include => :pages

Nun ist diese, wo ich bin verwirrt. Mein Verständnis ist, dass @book.pages bereits geladen ist und nicht eine andere Abfrage auszuführen. Aber angenommen, ich möchte eine bestimmte Seite zu finden, was würde ich tun?

@book.pages.find page_id

# OR...

@book.pages.to_ary.find{|p| p.id == page_id}

Bin ich recht in der Annahme, dass das erste Beispiel eine weitere Abfrage ausgeführt wird, und daher macht die eifrig Laden sinnlos, oder aktiv ist Rekord klug genug, um zu wissen, dass es nicht eine andere Abfrage zu tun braucht?

Auch meine zweite Frage, gibt es ein Argument, dass in einigen Fällen eifrig Belastung der Datenbank intensiver und manchmal mehr kleine Abfragen werden effiziente, dass eine einzige große Abfrage?

Vielen Dank für Ihre Meinung.

War es hilfreich?

Lösung

Wenn Active eifrig einen Verein lädt, was in den Eingeweiden des Objekts geschieht tief ist eine Instanzvariable eingestellt wird. Das ist es, keine Zauberei. Alle Methoden, die von Enumerable und der Active :: AssociationProxy einfach auf den Instanzvariable aussehen zu wissen, ob sie geladen wurde oder nicht, und dann mit ihrem Geschäft fortgefahren wird.

Wenn Sie anrufen #find, du bist nicht die Sammlung Laden: Sie suchen für eine bestimmte Instanz. Sie sprechen nicht auf die Sammlung selbst.

Ihr zweites Beispiel wäre der Weg zu gehen, aber ich würde es anders machen:

@book.pages.detect {|p| p.id == page_id}

Alternativ und ich hier einige Dinge über Ihre Bewerbung unter der Annahme, ich würde es in einer noch besseren Art und Weise tun:

class BooksController < ApplicationController
  def show
    @book = Book.find(params[:id], :include => :pages)
    @pages_by_id = @book.pages.index_by(&:id)
  end
end

# app/views/books/show.html.erb
Page: <%= @pages_by_id[page_id].number %>

Hinweis Ich verwende #index_by, die einen Hash zurück, wo die Schlüssel sind das Ergebnis eines Blocks zu bewerten und die Werte sind das ursprüngliche Objekt. Da Sie nur scheinen auf Seiten von ID finden wollen, ist es sinnvoll einen Hash die zu haben.

Ihr Punkt, um mehr oder weniger intensiv auf der Datenbank zu sein, ist ein guter, und eine, die Bären halten zu jeder Zeit im Auge behalten. Wenn Sie die meisten der zurückgegebenen Daten verwenden werden, wird es Sinn machen. Wenn Sie nur eine kleine Teilmenge der Daten verwenden, ist es nicht sinnvoll, alle die Daten für diese Objekte zum Download, nur sie später an den Garbage Collection Millisekunden zu werfen.

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