Así es como tengo mi prueba de controlador, solo para mostrar qué estructura de solicitud funciona:
post( :create, params: { play_session: { comment: "COMMENT", time_in_minutes: 10, video: fixture_file_upload("video.webm") } } )Estoy tratando de llegar a este punto final desde JS con esto:
async function uploadFile(blob) { let play_session = { comment: "SUPER GOOD COMMENT", time_in_minutes: 23, video: blob }; let formData = new FormData(); formData.append("play_session", play_session); try { let response = await fetch( "http://localhost:3000/front/play_sessions", { method: "POST", body: formData } ); console.log("HTTP response:", response); } catch(e) { console.log("Huston we have problem...:", e); } }Pero me sale este error en la consola de Rails:
Started POST "/front/play_sessions" for ::1 at 2021-09-24 22:00:30 +0200 Processing by Front::PlaySessionsController#create as */* Parameters: {"play_session"=>"[object Object]"} Completed 500 Internal Server Error in 3ms (Allocations: 1717) NoMethodError (undefined method `permit' for "[object Object]":String): He intentado agregar encabezados a la llamada de fetch de esta manera:
await fetch( "http://localhost:3000/front/play_sessions", { method: "POST", headers: { "Accept": "application/json", "Content-Type": "multipart/form-data" }, body: formData } );Entonces tengo este error en la consola de Rails:
Started POST "/front/play_sessions" for ::1 at 2021-09-24 22:02:59 +0200 Processing by Front::PlaySessionsController#create as JSON Parameters: {"------WebKitFormBoundaryESNX0mluVZ8VIiry\r\nContent-Disposition: form-data; name"=>"\"play_session\"\r\n\r\n[object Object]\r\n------WebKitFormBoundaryESNX0mluVZ8VIiry--\r\n"} Completed 400 Bad Request in 1ms (Allocations: 520) ActionController::ParameterMissing (param is missing or the value is empty: play_session Did you mean? ------WebKitFormBoundaryESNX0mluVZ8VIiry Content-Disposition: form-data; name action controller):El anexo de FormData acepta pares de name y value donde el value puede ser una cadena o un blob.
valor
El valor del campo. Puede ser un USVString o Blob (incluidas subclases como File). Si no se especifica ninguno de estos, el valor se convierte en una cadena.
Aquí, formData.append("play_session", play_session) asigna un objeto.
Debido a que Rails es inteligente para crear hashes y matrices en parámetros, debe agregar los parámetros de play_session uno por uno:
let formData = new FormData(); formData.append('play_session[comment]', 'SUPER GOOD COMMENT') formData.append('play_session[time_in_minutes]', 23) formData.append('play_session[video]', blob)Para atributos anidados debes hacer:
formData.append('play_session[user_attributes][name]', 'Jack');Para arreglos:
formData.append('play_session[user_ids][]', "1"); formData.append('play_session[user_ids][]', "2");