2 Stimmen

RailsTutorial 3.2 Kapitel 11 - PostgreSQL Syntaxfehler unterbricht den Status-Feed

Ich bin in Abschnitt 11.3.1 des Rails-Tutorials, und alle Tests waren vorher erfolgreich. Danach bricht die Startseite (die den Micropost-Feed enthält) mit diesem Fehler ab:

PG::Error: ERROR:  invalid input syntax for integer: "98, 1"
LINE 1: ...CT COUNT(*) FROM "microposts"  WHERE (user_id IN ('98, 1') O...
                                                             ^
: SELECT COUNT(*) FROM "microposts"  WHERE (user_id IN ('98, 1') OR user_id = 101)

Und mehrere der Tests scheitern an einem ähnlichen Problem. Hier ist der erste:

1) Authentication authorization as wrong user visiting Users#edit page 
   Failure/Error: before { visit edit_user_path(wrong_user) }
   ActionView::Template::Error:
   PG::Error: ERROR:  invalid input syntax for integer: ""
   LINE 1: ...CT COUNT(*) FROM "microposts"  WHERE (user_id IN ('') OR use...
                                                                ^

Ich verwende PostgreSQL anstelle des Standard-SQLite3, es kann also sein, dass es einen Syntaxkonflikt gibt, aber ich bin mir nicht sicher. Ich bin nicht super vertraut mit Postgres (ich verwende es nur, um die Heroku Bereitstellung sauberer zu machen).

Es sieht so aus, als ob der Homepage-Fehler von den ids kommt, die mit Anführungszeichen an die Abfrage übergeben werden - ich ging in psql, um ein paar Abfragen zu testen, und das ist erfolgreich:

SELECT "microposts".* FROM "microposts" WHERE "microposts"."id" IN (1,2,3);

während dies nicht gelingt:

SELECT "microposts".* FROM "microposts" WHERE "microposts"."id" IN ('1,2,3');

Und der spec-Fehler kommt von einem leeren Array übergeben wird, äquivalent zu diesem, die auch fehlschlägt:

SELECT "microposts".* FROM "microposts" WHERE "microposts"."id" IN ('');

Kann mir jemand, der mit der PostgreSQL-Syntax vertraut ist, sagen, wie ich die Methodendefinition umschreiben kann, um dieses Problem zu beheben?

Die derzeitige Methode in micropost.rb sieht so aus:

def self.from_users_followed_by(user)
    followed_user_ids = user.followed_user_ids.join(', ')
    where("user_id IN (?) OR user_id = ?", followed_user_ids, user)
end

Und der Aufruf von `users.rb' sieht wie folgt aus:

def feed
    Micropost.from_users_followed_by(self)
end

0 Stimmen

Vorbereitete Anweisungen scheitern, wenn Sie etwas wie den Aufbau einer IN(...) Liste - der Ersteller ist ziemlich dumm und erkennt nicht, dass es sich um eine durch Kommata getrennte Liste und nicht um einen einzigen festen Datenblock handeln sollte.

8voto

ellawren Punkte 947

Heilige Scheiße, das habe ich tatsächlich selbst herausgefunden. Ich musste nur die Verknüpfung in der Methodendefinition entfernen:

def self.from_users_followed_by(user)
    followed_user_ids = user.followed_user_ids
    where("user_id IN (?) OR user_id = ?", followed_user_ids, user)
end

user.followed_user_ids.join(', ') produziert dies: "1, 2, 3"

während

user.followed_user_ids produziert dies: 1, 2, 3

was ich auch wollte.

1 Stimmen

Richtig. Wenn Sie join in Ruby erhalten Sie einen einzelnen String, den AR zitiert; aber PostgreSQL weiß nicht, was int IN (string) bedeutet, dass Sie einen Fehler erhalten. Wenn Sie die Hand where ein Array, wird es jedes Element in Anführungszeichen setzen (je nach Bedarf), die Elemente in Anführungszeichen mit Kommas verbinden und das Ergebnis in SQL ausgeben; PostgreSQL weiß, was int IN (int, int, ...) bedeutet, dass es funktioniert. Übrigens können Sie Ihre eigenen Antworten akzeptieren.

0 Stimmen

Das scheint kein Postgres-Problem zu sein, sondern eher ein Fehler im Tutorial, oder?

1 Stimmen

Stimmt, aber das habe ich erst gemerkt, nachdem ich die Antwort gefunden hatte. Ich habe den Autor per E-Mail darüber informiert, und er sagte, es sei ein echter Fehler und werde in der nächsten Überarbeitung behoben (wahrscheinlich ist er das bereits).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X