Klonen einer Relation in Schienen

9

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.

Deprecation-Fehler

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

    
Yule 20.03.2015, 14:41
quelle

4 Antworten

5

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 Ссылка .

    
marcus3006 20.04.2015, 19:23
quelle
1

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.

%Vor%

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:

  1. suche deinen Code nach diesen Bang-Methoden, vielleicht einen Affen-Patch, der auf AR gemacht wurde.
  2. überprüfe die Edelsteine, die du benutzt. Vielleicht solltest du eine neue App starten, in der der Code funktioniert, und alle Edelsteine ​​hinzufügen, die du in deiner Ziel-App hast. Wenn das nicht klappt, kannst du versuchen, Edelsteine ​​zu entfernen, bis sie wieder funktioniert.

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.

%Vor%

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.

    
Alejandro Babio 16.04.2015 22:00
quelle
0

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.

    
user4426213 18.04.2015 00:18
quelle
-2

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:

Könnte es wert sein, Ihren Code mit dem Master-Zweig der Schienen auszuprobieren.

    
Prakash Murthy 20.03.2015 16:39
quelle