Я создал приложение-клон в Instagram, и пользователь может создать сообщение (Sighting
) с фотографией.Заголовок и текст сообщения являются простыми fetch
для моего бэкэнда Rails sightings#create
.Прикрепленная фотография с другой стороны использует библиотеку npm, называемую Active Storage Provider (<ActiveStorageProvider />
), с собственным методом передачи изображения в direct_upload
в Rails и в AWS S3.
Это легко сделать, если пользователь присоединяется позже, потому что уже существует Sighting
, и у меня есть отдельный метод и маршрут для этого в моем SightingsController
, называемый def image_upload
.На create
еще нет экземпляра Sighting
, потому что все это происходит «одновременно».Будучи новичком, как можно обрабатывать обе выборки одновременно?
Вот мой sighting
метод пост-выборки:
postSighting = (title, body, animalId) => {
fetch(`http://localhost:9000/api/v1/sightings`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": localStorage.getItem("token")
},
body: JSON.stringify({
title: title,
body: body,
likes: 0,
image: null,
animal_id: animalId,
user_id: this.state.currentUser.id
})
})
.then(r => r.json())
.then(newSighting => {
this.setState({ sightings: [newSighting, ...this.state.sightings]})
})
}
и вот вспомогательный компонент библиотеки для Active Storage, отправляющий в React:
<ActiveStorageProvider
endpoint={{
protocol: 'http',
method: 'PUT',
attribute: 'image',
host: 'localhost',
port: '9000',
model: 'Sighting',
path: `http://localhost:9000/api/v1/sightings/image_upload/${this.props.match.params.id}`
}}
onSubmit={user => this.setState({ image: user.image })}
render={({ handleUpload, uploads, ready }) => (
<div>
<Input
type="file"
disabled={!ready}
onChange={e => handleUpload(e.currentTarget.files)}
/>
{uploads.map(upload => {
switch (upload.state) {
case 'waiting':
return <p key={upload.id}>Waiting to upload {upload.file.name}</p>
case 'uploading':
return (
<p key={upload.id}>
Uploading {upload.file.name}: {upload.progress}%
</p>
)
case 'error':
return (
<p key={upload.id}>
Error uploading {upload.file.name}: {upload.error}
</p>
)
case 'finished':
return (
<p key={upload.id}>Finished uploading {upload.file.name}</p>
)
}
})}
</div>
)}
/>