ember-active-storage v1.0.1
ember-active-storage
Installation
ember install ember-active-storageUsage
The addon provides an activeStorage service that allows you to:
- send files to your Rails backend's direct upload controller;
- listen to upload progress events.
Assuming your template has a file input like:
<input type="file" onchange={{action "upload"}} />and your ember model has an avatar attribute defined as has_one_attached :avatar on its corresponding Active Record model, then in your component (or controller) the upload action would look like:
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { get, set } from '@ember/object';
export default Component.extend({
activeStorage: service(),
uploadProgress: 0,
actions: {
upload(event) {
const files = event.target.files;
if (files) {
const directUploadURL = '/rails/active_storage/direct_uploads';
for (var i = 0; i < files.length; i++) {
get(this, 'activeStorage').upload(files.item(i), directUploadURL, {
onProgress: (progress) => {
set(this, 'uploadProgress', progress);
}
}).then( (blob) => {
const signedId = get(blob, 'signedId');
let model = get(this, 'model');
set(model, 'avatar', signedId);
});
}
}
}
}
});directUploadURLis the path referencingActiveStorage::DirectUploadsControlleron your Rails backend (or a custom one built on top of that).- The
uploadProgressproperty will hold a value between 0 and 100 that you might use in your template to show upload progress. - After the
uploadpromise is resolved andsignedIdis set in your model, when amodel.save()is triggered, the Rails backend will use suchsignedIdto associate anActiveStorage::Attachmentrecord to your backend model's record.
Sending authentication headers
It's pretty common that you want to protect with authentication the direct uploads endpoint on your Rails backend. If that's the case, the activeStorage service will need to send authentication headers together with the direct upload request.
To achieve that, you'll need to extend the activeStorage service provided by the addon and add a headers computed property. For example, if you're using ember-simple-auth, it will be a 2-steps process. First you'll need to define an authenticatedHeaders computed property in your session service, like this:
// app/services/session.js
import SessionService from 'ember-simple-auth/services/session';
import { computed, get } from '@ember/object';
export default SessionService.extend({
authenticatedHeaders: computed('isAuthenticated', function() {
const { access_token } = get(this, 'session.authenticated');
return { Authorization: `Bearer ${access_token}` };
})
});Then, you will alias that property in your activeStorage service, like this:
// app/services/active-storage.js
import ActiveStorage from 'ember-active-storage/services/active-storage';
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
export default ActiveStorage.extend({
session: service(),
headers: alias('session.authenticatedHeaders')
});Also note: if the download endpoint is protected as well, and you're using an ajax request to download files, then don't forget to include the same headers in that request as well.
Contributing
Installation
git clone <repository-url>cd ember-active-storageyarn install
Linting
yarn lint:jsyarn lint:js --fix
Running tests
ember test– Runs the test suite on the current Ember versionember test --server– Runs the test suite in "watch mode"yarn test– Runsember try:eachto test your addon against multiple Ember versions
Running the dummy application
ember serve- Visit the dummy application at http://localhost:4200.
For more information on using ember-cli, visit https://ember-cli.com/.
License
This project is licensed under the MIT License.