RailsTutorial 3.2 Ch 11 - L'errore di sintassi di PostgreSQL interrompe il feed di stato
-
29-10-2019 - |
Domanda
Sono nella Sezione 11.3.1 del Rails Tutorial e tutti i test erano passati prima di questo. Successivamente, la home page (che ha il feed di micropost) si interrompe con questo errore:
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)
E molti dei test falliscono con un problema simile. Ecco il primo:
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...
^
Ora, sto usando PostgreSQL al posto del SQLite3 predefinito, quindi potrebbe esserci un conflitto di sintassi, ma non sono positivo. Non ho molta familiarità con Postgres (lo uso solo per rendere il deployment di Heroku più pulito).
Sembra che l'errore della home page provenga dagli ID passati alla query tra virgolette: sono entrato in psql per testare alcune query e questo ha avuto successo:
SELECT "microposts".* FROM "microposts" WHERE "microposts"."id" IN (1,2,3);
mentre questo fallisce:
SELECT "microposts".* FROM "microposts" WHERE "microposts"."id" IN ('1,2,3');
E l'errore di specifica proviene dal passaggio di un array vuoto, equivalente a questo, che anch'esso fallisce:
SELECT "microposts".* FROM "microposts" WHERE "microposts"."id" IN ('');
Chiunque abbia familiarità con la sintassi di PostgreSQL può dirmi come riscrivere la definizione del metodo per risolvere questo problema?
Il metodo corrente in micropost.rb
è simile a questo:
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
E la chiamata da `users.rb 'ha questo aspetto:
def feed
Micropost.from_users_followed_by(self)
end
Soluzione
Porca miseria, l'ho capito da solo.Dovevo solo rimuovere il join nella definizione del metodo:
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(', ')
produce questo: "1, 2, 3"
mentre
user.followed_user_ids
produce questo: 1, 2, 3
che è quello che volevo.