如何在LoopBack中存储带有元数据的文件? [英] How to store files with meta data in LoopBack?

查看:72
本文介绍了如何在LoopBack中存储带有元数据的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做什么: 具有html表单,其中包含文件输入.选择文件后,文件输入应上传文件并获取文件ID,因此,在提交表单时,文件ID将与表单一起发布并写入数据库.

What I want to do: Have an html form, with a file input inside. When a file is chosen, the file input should upload the file, and get a file id, so when the form is submitted, the file id is posted with the form and written in the database.

更短版本:我想在文件中存储元数据(例如id).

听起来很简单,但是我很难在LoopBack中做到这一点.

Sounds simple, yet I struggle to do that in LoopBack.

进行了几次对话( 1 2 ),但似乎都没有找到解决方案,所以我认为这可能是一次找到一个好地方并为所有人.

There has been a couple conversations ( 1, 2 ) about this topic, and neither seemed to lead to a solution, so I thought this might be a good place to find one once and for all.

最简单的解决方案是使用模型关系,但是LoopBack不支持与文件存储服务的关系.撞.因此,我们必须使用名为File的持久模型,并覆盖默认的create,delete,以便它从我拥有的名为Storage的文件存储模型中进行保存和删除.

The simplest solution would be to use model relations, but LoopBack doesn't support relations with the file storage service. Bump. So we have to go with a persistedmodel named File for example, and override default create, delete so it saves and deletes from the file store model I have - named Storage.

到目前为止,我的设置是

My setup so far:

  • 我有一个/api/Storage模型,该模型已连接到回送存储服务和正在将文件成功保存到本地文件系统.
  • 我有一个通过文件元数据连接到Mongo的PersistedModel:namesizeurlobjectId
  • 我在create之前设置了远程挂钩,因此可以先保存文件,然后将其url注入File.create()
  • I have a model /api/Storage which is connected to a loopback storage service and is saving file successfully to the local filesystem.
  • I have a PersistedModel connected to Mongo with file meta data: name,size, url and objectId
  • I have a remote hook set up beforecreate so the file can be saved first and then it's url can be injected into File.create()

我在那里,并且根据此LoopBack页面,我有ctx该文件应位于其中:

I'm there, and according to this LoopBack page, I have the ctx which should have the file inside:

File.beforeRemote('create', function(ctx, affectedModelInstance, next) {})`

什么是ctx?

ctx.req:Express请求对象.
ctx.result:Express Response对象.

ctx.req: Express Request object.
ctx.result: Express Response object.

好吧,所以现在我在Express页面上,很迷路,它说了一些关于人体分析中间件"的东西,我不知道它可能是什么.

Ok, so now I'm at the Express page, pretty lost, and it sais something about a 'body-parsing middleware' which I have no idea what it might be.

我觉得我已经接近解决方案了,我们将不胜感激.这种方法正确吗?

I feel like I'm close to the solution, any help would be appreciated. Is this approach right?

推荐答案

以下是 full 解决方案,用于存储带有回送功能的元数据和文件.

Here's the full solution for storing meta data with files in loopback.

您需要一个容器模型

common/models/container.json

{
  "name": "container",
  "base": "Model",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {},
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": []
}

server/datasources.json中为您的容器创建数据源.例如:

Create the data source for your container in server/datasources.json. For example:

...
"storage": {
    "name": "storage",
    "connector": "loopback-component-storage",
    "provider": "filesystem", 
    "root": "/var/www/storage",
    "maxFileSize": "52428800"
}
...

您需要将server/model-config.json中此模型的数据源设置为您拥有的loopback-component-storage:

You'll need to set the data source of this model in server/model-config.json to the loopback-component-storage you have:

...
"container": {
    "dataSource": "storage",
    "public": true
}
...

您还需要一个文件模型来存储元数据并处理容器调用:

You'll also need a file model to store the meta data and handle container calls:

common/models/files.json

{
  "name": "files",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "name": {
      "type": "string"
    },
    "type": {
      "type": "string"
    },
    "url": {
      "type": "string",
      "required": true
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": []
}

现在将filescontainer连接:

common/models/files.js

var CONTAINERS_URL = '/api/containers/';
module.exports = function(Files) {

    Files.upload = function (ctx,options,cb) {
        if(!options) options = {};
        ctx.req.params.container = 'common';
        Files.app.models.container.upload(ctx.req,ctx.result,options,function (err,fileObj) {
            if(err) {
                cb(err);
            } else {
                var fileInfo = fileObj.files.file[0];
                Files.create({
                    name: fileInfo.name,
                    type: fileInfo.type,
                    container: fileInfo.container,
                    url: CONTAINERS_URL+fileInfo.container+'/download/'+fileInfo.name
                },function (err,obj) {
                    if (err !== null) {
                        cb(err);
                    } else {
                        cb(null, obj);
                    }
                });
            }
        });
    };

    Files.remoteMethod(
        'upload',
        {
            description: 'Uploads a file',
            accepts: [
                { arg: 'ctx', type: 'object', http: { source:'context' } },
                { arg: 'options', type: 'object', http:{ source: 'query'} }
            ],
            returns: {
                arg: 'fileObject', type: 'object', root: true
            },
            http: {verb: 'post'}
        }
    );

};

要公开将api文件添加到files模型的model-config.json文件中,请记住选择正确的数据源:

For expose the files api add to the model-config.json file the files model, remember select your correct datasources:

...
"files": {
    "dataSource": "db",
    "public": true
}
...

完成!您现在可以在file表单字段中使用文件二进制数据调用POST /api/files/upload.您将获得ID,名称,类型和url作为回报.

Done! You can now call POST /api/files/upload with a file binary data in file form field. You'll get back id, name, type, and url in return.

这篇关于如何在LoopBack中存储带有元数据的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆