Seltsam
Seltsam

Reputation: 944

Maintain uploaded Pictures with Express and Mongodb - Best practise?

I'm working on a little service (Express, Mongodb) where Users can upload Images to their accounts in various places. Before I dive in I'd like to make sure I have the right strategy to manage(store, edit, delete, load) these uploaded pictures.

My initial idea was to

  1. Upload the pictures into a folder with the users-id
  2. Save a directory-link as string in the users db-model
  3. And then in the frontend paste the url-strings into img-src

What really bugs me about this approach, is that the images basically need to be maintained (change image-names, delete images, add images, ...) in two places, the db-model (urls-strings) and the upload-folder-structure (path, image-names). This probably could be made easier with a set of helper-functions.

But still, is there a more elegant way to manage images with Mongodb and Express? Any best practise here?

Upvotes: 2

Views: 240

Answers (2)

Seltsam
Seltsam

Reputation: 944

@Sergio This is how I approached it now. How would you work in the functionality for the randomized filenames? Thanks

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var ImageSchema = new Schema({
  name: String,
  _id:false
})

ImageSchema.virtual('url').get(function () {
  var parent = this.parent()
  var root = (parent.parent ? parent.parent() : parent)
  return root.category + "/" + root.path +"/"+ this.name
});

ImageSchema.set('toJSON', {
    virtuals: true
});

var CombinationSchema = new Schema({
  name: String,
  description: String,
  images: [ImageSchema],
  _id:false
})

var CasinoSchema = new Schema({
    name: String,
    category: {
        type: String,
        default: 'casino'
    },
    images: [ImageSchema],
    path: String,
    description: String,
    combinations: [CombinationSchema]
})

module.exports = mongoose.model('casinos', CasinoSchema)

Upvotes: 0

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230346

It's more or less like you described. You need to store an image somewhere (local filesystem or S3, doesn't matter) and you need a record in your database to reference it. And then use it somehow (render as img src or whatever). So you will have to do these three things, no way around it. Of course, cleaner/better code will make your life easier.

I'd like to advise against one thing, though: renaming files in the storage. That is fragile/error-prone. What if renaming fails, because there is already a file with this name?

Instead, store all files with random names (sha-1 of content or random uuid or something else) and store the original filename in your database (along with the actual file path, of course). This way, should you need it, you'll be able to "rename" the file without touching the storage.

Upvotes: 2

Related Questions