JavaScript HTML
Permalink
Failed to load latest commit information.
addon
app
config
tests
vendor
.bowerrc
.editorconfig
.ember-cli
.gitignore
.jscsrc
.jshintrc
.npmignore
.travis.yml
.watchmanconfig
LICENSE.md
README.md
bower.json
ember-cli-build.js
index.js
jsdoc.json
package.json
testem.js

README.md

Ember Data Paperclip

Build Status Ember Observer Score

This addon provides an ember file attribute to use with rails paperclip. A demo can be found here.

Installation

Install the addon with the following command:

ember install ember-data-paperclip

After installation, you can optionally add the serializer-mixin to your serializer. You only need this if you want to use model properties in your file path (see configuration point 4).

// app/serializers/application.js

import ActiveModelSerializer from 'active-model-serializer';
import SerializerMixin from 'ember-data-paperclip/mixins/serializer-mixin';

export default ActiveModelSerializer.extend(SerializerMixin);

Configuration

This addon needs some configuration before you can use it. Add the following to your config/environment.js:

// config/environment.js

  ...

  paperclip: {
    path: ':class/:attachment/:id_partition/:style/:filename.jpg'
  },

  ...

The variables that are used above are available by default. If you need other variables or want to override the default ones, there are three ways to do that:

  1. Directly in your config file. For example, if your path begins with :base, you can add base like this:

     // config/environment.js
    
       ...
    
       paperclip: {
         path: ':base/:class/:attachment/:id_partition/:style/:filename.jpg',
         base: 'https://files.example.com'
       },
    
       ...
  2. By adding options on the attribute. For example if the filename is always 'data':

     // app/models/product.js
    
     import Model from 'ember-data/model';
     import attr from 'ember-data/attr';
    
     export default Model.extend({
       photo: attr('file', {
         filename: 'data'
       })
     });
  3. By sending it from the backend. For example with rails active model serializers:

     # app/serializers/product_serializer.rb
    
     class ProductSerializer < ActiveModel::Serializer
       attributes :id, :photo
    
       def photo
         if object.photo.present?
           {
             filename: object.photo_file_name
           }
         end
       end
     end
  4. By providing them on your model. For example if you want to override id_partition:

     // app/models/product.js
    
     import Model from 'ember-data/model';
     import attr from 'ember-data/attr';
     import Ember from 'ember';
    
     const { computed } = Ember;
    
     export default Model.extend({
       photo: attr('file'),
    
       id_partition: computed('id', function() {
         return this.get('id');
       })
     });

    Please note that this requires the SerializerMixin to be included in your serializer.

Usage

In your model add a file attribute:

// app/models/product.js

import Model from 'ember-data/model';
import attr from 'ember-data/attr';

export default Model.extend({
  photo: attr('file')
});

Getting

You can generate urls for different styles like this:

var url = product.get('photo').url();
// products/photos/000/000/001/original/data.jpg

var thumbnailUrl = product.get('photo').url('thumbnail');
// products/photos/000/000/001/thumbnail/data.jpg

You can retrieve the object URL of the file like this:

product.get('photo').objectURL('thumbnail').then((thumbnailObjectURL) => {
  console.log(thumbnailObjectURL);
});

You can also retrieve the base64 data URL of the file:

product.get('photo').dataURL('thumbnail').then((thumbnailDataURL) => {
  window.open(thumbnailDataURL);
});

Utilities to use these urls like computed properties are available as well:

import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import fileURL from 'ember-data-paperclip/utils/file-url';
import dataURL from 'ember-data-paperclip/utils/data-url';
import objectURL from 'ember-data-paperclip/utils/object-url';

export Model.extend({
  photo: attr('file'),

  photoThumbnailURL: fileURL('photo', 'thumbnail'),

  photoThumbnailDataURL: dataURL('photo', 'thumbnail'),

  photoObjectURL: objectURL('photo')
});

A template helper is also available:

<img src={{file-url product.photo 'thumbnail'}} />

Setting

You can set the file from a file upload like this:

  ...

  change: function (e) {
    this.get('product.photo').update(e.target.files[0]);
  },

  ...

A file-upload component is also provided:

{{file-upload file=product.photo}}

When saving, this will cause the following request:

// POST /products/1

{
  "product": {
    "id": 1,
    "photo": "[base64data]"
  }
}

The photo will only be sent to your backend when it has changed. You can also remove the photo:

product.get('photo').clear();
product.save();

This will send the following to the backend:

// POST /products/1

{
  "product": {
    "id": 1,
    "photo": null
  }
}

Limitations

  • FormData is not yet supported. Uploads happen using json and base64 at the moment.
  • The optional serializer mixin overrides some of the internal transform logic. This currently only works for the json and active model serializers.

License

This project is released under the MIT License.