Ich erhalte bei einem Upgrade auf Rails 4.2.1, Modifying already cached Relation. The cache will be reset. Use a cloned Relation to prevent this warning.
Die Aktion, die ich ausführen möchte, erhält die Anzahl der Benutzer pro Monat, die sich angemeldet haben.
Mein Test ist einfach:
%Vor%Controller Aktion:
%Vor%Benutzermodell
%Vor%Ich stelle fest, dass ich fast die gleiche Abfrage 12 Mal, aber mit verschiedenen Parametern ausgeführt habe. Diese Methode wird an anderer Stelle verwendet, wenn die Benutzer nicht gruppiert sind. Wie kann ich eine Beziehung "klonen", wie in der Verwarnungswarnung vorgeschlagen?
Ich möchte das nicht einfach ignorieren, da es meinen Bildschirm füllt, während ich Tests durchführe, was nicht sehr hilfreich ist
In meinem Fall war es der Quietscher-Edelstein, der die Verwarnungswarnung produziert. Ein einfacher Monkeypatch behebt die Warnung.
%Vor%Ich bin nicht sicher, ob es Quietschverhalten bricht, aber es funktioniert für mich. Es scheint ein Problem mit Rails 4.2.x in Kombination mit Quietschen zu sein. Ich habe dies auch in den Quietschetiketten-Tracker geschoben Ссылка .
Bearbeitet
In erster Linie funktioniert Ihr Code . Es erhöht nicht ImmutableRelation
oder zeigt abnormierte Nachrichten an, die auf Schienen laufen. 4.2.1.
Der Code auf Ihrer Seitenaktion muss keine Beziehung klonen, da er in jedem Monatsschritt eine neue erstellt (mit: User...
). Ja, es gibt 12 Abfragen, aber es ist kein Problem für Sie.
Es ist nicht so wichtig, aber Sie haben zwei Tippfehler bei der Frage. Ihr Modell muss def number_first_logged_in(month)
mit def self.number_first_logged_in(month)
ändern und der Modellname muss User
und nicht Model
sein.
Ich teste es auf der rails-Konsole (über Products
anstelle von User
und% :created_at
anstelle von :first_logged_in_at
-Feld), aber es ist das gleiche und funktioniert gut. Und ich bin mir ziemlich sicher, dass wenn Sie eine neue Rails 4.2.1 App starten und den Code bei der Frage verwenden (mit festgesetzten Tippfehlern), wird es funktionieren.
Aber Sie haben ein Problem . Dieses Problem bezieht sich nicht auf die API für öffentliche Schienen, da es keine Methoden gibt, die diesen Fehler oder diese Abwertung auslösen könnten. Das Rails-Team sagt, dass jede #nodoc
public-Methode nicht Teil der öffentlichen API ist. Viele der Abfragemethoden (wenn nicht alle) haben eine Paar-Bang-Methode ( code ), wodurch die Beziehung geändert wird (anstatt einen Klon zurückzugeben) und der InmutableRelation
-Fehler (oder die veraltete Nachricht der vorherigen Version) ausgelöst wird. Diese public -Methoden sind #nodoc
und nicht Teil der öffentlichen Rails-API.
Was ist zu tun? Es ist nicht einfach:
Ich beziehe mich auf die Bang-Methoden, aber es gilt auch für die Methode, die die Beziehung ändert (dies kann nicht von der öffentlichen API durchgeführt werden). Sie müssen nach Affenpflaster suchen oder sich über die Beziehung erstrecken.
Das muss ausreichen, um das Problem zu beheben.
Ich habe Ihren Kommentar gelesen, und ich habe den Punkt, ich denke diese Optionen:
Rails Datenbank-Unabhängigkeit funktioniert durch arel. Und Arel hat keine Methoden, um direkt mit db-Funktionen zu arbeiten (Monat eines Datumsfeldes). Sie können arel erweitern und schreiben, aber Sie müssen einen für schreiben PostgreSql eine für MySql andere für Sqlite. (Zu teuer, dabei Punkt)
Wenn Sie denselben DB-Manager für dev / test / prod verwenden, können Sie einen partiellen verwenden Textabfrage wie ich vorgeschlagen habe. (Das mag dich nicht)
Behalte die 12 Fragen (ich denke du kannst damit leben)
Fügen Sie ein eigenes Feld zu group_by hinzu (year_month könnte sein). (Sehr rigig, schwer zu ändern)
Ich behalte die alte Antwort , denn: Wenn ich du wäre, würde ich so etwas tun:
%Vor%Auf der Aktion der Controller-Seite können Sie Folgendes verwenden: (Ich empfehle die Verwendung)
%Vor%Gibt einen Hash mit diesem Muster zurück: (mehr von hier ) )
%Vor% Wenn Sie jedoch das gleiche @months
wie zuvor erhalten möchten, müssen Sie das Ergebnis mit Ruby abbilden.
Hinweis1: Dieser Code funktioniert für PostgreSQL, da er die Funktion date_trunc(...)
verwendet, wenn Sie mit MySql arbeiten müssen, verwenden Sie stattdessen month(users.created_at)
. Beim Mappen mit MySql müssen Sie k[0]
anstelle von k[0].month
verwenden.
Hinweis2: Der group
-Aufruf hat Parameter für seine Felder getrennt, weil Sie zwei Werte für den Schlüssel des zurückgegebenen Hashes haben möchten.
Ich sehe zwei mögliche Lösungen:
Sie können den Cache zwischen Abfragen löschen: %Code% von Löschen des aktiven Datensatz-Cache
Sie können ActiveRecord::Base.connection.query_cache.clear
verwenden, um die Beziehung zu klonen, bevor Sie sie manipulieren, damit Sie den Cache nicht ungültig machen.
Kurze Antwort:
Ignoriere es. Die Deprecation-Nachricht wurde aus dem Master-Zweig von Rails entfernt. Rails 5 wird sich nicht darüber beschweren.
Lange Antwort:
Die folgenden Probleme / Commits scheinen den Eindruck zu erwecken, dass die veraltete Nachricht versehentlich hinzugefügt und entfernt wurde:
@arel
zurück, wenn Sie eine Relation vor Ort ändern. Könnte es wert sein, Ihren Code mit dem Master-Zweig der Schienen auszuprobieren.
Tags und Links ruby-on-rails rails-activerecord rails-4-2-1 adequate-record