【问题标题】:MDG ValidatedMethod with Aldeed Autoform: "_id is not allowed by the schema" errorMDG ValidatedMethod 与 Aldeed Autoform:“架构不允许 _id”错误
【发布时间】:2016-05-06 03:05:05
【问题描述】:

我在尝试使用自动表单通过 ValidatedMethod 更新集合时收到错误“_id is not allowed by the schema”。

据我从 this exampleofficial docs 可以看出,我的架构不希望包含 _id 字段,我也不希望从更新语句中更新 id,所以我有不知道为什么会发生这个错误。

如果我从使用经过验证的方法切换到直接写入集合(将架构附加到没有 id 的集合),一切都会按预期工作,所以我假设问题出在我的在我的 ValidatedMethod 中验证。

知道我做错了什么吗?

模板:customer-edit.html

<template name="updateCustomerEdit">
    {{> quickForm
        collection="CustomerCompaniesGlobal"
        doc=someDoc
        id="updateCustomerEdit"
        type="method-update"
        meteormethod="CustomerCompanies.methods.update"
        singleMethodArgument=true
    }}
</template>

模板“代码隐藏”:customer-edit.js

Template.updateCustomerEdit.helpers({

    someDoc() {
        const customerId = () => FlowRouter.getParam('_id');
        const instance = Template.instance();

        instance.subscribe('CustomerCompany.get', customerId());

        const company = CustomerCompanies.findOne({_id: customerId()});
        return company;
    }
});

更新验证方法:

// The update method
update = new ValidatedMethod({

    // register the name
    name: 'CustomerCompanies.methods.update',

    // register a method for validation, what's going on here?
    validate: new SimpleSchema({}).validator(),

    // the actual database updating part validate has already been run at this point
    run( newCustomer) {
    console.log("method: update");
        return CustomerCompanies.update(newCustomer);
    }
});

架构:

Schemas = {};

Schemas.CustomerCompaniesSchema = new SimpleSchema({

    name: {
        type: String,
        max: 100,
        optional: false
    },

    email: {
        type: String,
        max: 100,
        regEx: SimpleSchema.RegEx.Email,
        optional: true
    },

    postcode: {
        type: String,
        max: 10,
        optional: true
    },

    createdAt: {
        type: Date,
        optional: false
    }
});

收藏:

class customerCompanyCollection extends Mongo.Collection {};

// Make it available to the rest of the app
CustomerCompanies = new customerCompanyCollection("Companies");
CustomerCompaniesGlobal = CustomerCompanies;

// Deny all client-side updates since we will be using methods to manage this collection
CustomerCompanies.deny({
    insert() { return true; },
    update() { return true; },
    remove() { return true; }
});

// Define the expected Schema for data going into and coming out of the database
//CustomerCompanies.schema = Schemas.CustomerCompaniesSchema

// Bolt that schema onto the collection
CustomerCompanies.attachSchema(Schemas.CustomerCompaniesSchema);

【问题讨论】:

    标签: meteor meteor-blaze meteor-autoform meteor-collection2 simple-schema


    【解决方案1】:

    我终于明白了。问题是 autoform 传入了一个复合对象,该对象表示要更改的记录的 id 以及数据的修饰符 ($set),而不仅仅是数据本身。所以那个对象的结构是这样的:

    _id: '5TTbSkfzawwuHGLhy',
    modifier:
    { 
      '$set':
        { name: 'Smiths Fabrication Ltd',
          email: 'info@smithsfab.com',
          postcode: 'OX10 4RT',
          createdAt: Wed Jan 27 2016 00:00:00 GMT+0000 (GMT Standard Time) 
        } 
    } 
    

    一旦我发现了这一点,我将我的更新方法更改为这个,然后一切都按预期工作:

    // Autoform specific update method that knows how to unpack the single
    // object we get from autoform.
    update = new ValidatedMethod({
    
        // register the name
        name: 'CustomerCompanies.methods.updateAutoForm',
    
        // register a method for validation.
        validate(autoformArgs) {
            console.log(autoformArgs);
            // Need to tell the schema that we  are passing in a mongo modifier rather than just the data.
            Schemas.CustomerCompaniesSchema.validate(autoformArgs.modifier , {modifier: true});
        },
    
        // the actual database updating part
        // validate has already been run at this point
        run(autoformArgs)
        {
            return CustomerCompanies.update(autoformArgs._id, autoformArgs.modifier);
        }
    });
    

    【讨论】:

      【解决方案2】:

      非常好。当我在努力寻找有关该主题的任何其他信息时,您的帖子帮助了我。

      为了建立您的答案,如果出于某种原因您希望将表单数据作为单个块获取,您可以在 AutoForm 中使用以下内容。

      type="method" meteormethod="myValidatedMethodName"
      

      您的验证方法可能如下所示:

      export const myValidatedMethodName = new ValidatedMethod({
        name: 'Users.methods.create',
        validate(insertDoc) {
          Schemas.NewUser.validate(insertDoc);
        },
        run(insertDoc) {
          return Collections.Users.createUser(insertDoc);
        }
      });
      

      注意:Schema.validate() 方法需要一个对象,而不是之前的修饰符。

      我不清楚这两种方法是否有任何明显的优势。

      type="method-update" 显然是您想要更新文档的方式,因为您获得了修饰符。 type="method" 似乎是创建新文档的最佳方式。在您不打算从表单数据创建文档的大多数情况下,它也可能是最佳选择。

      【讨论】:

      • 你不会这样回答问题。插入文档不像使用修饰符进行更新。下面的 tomRedox 答案是正确的。
      • 可以肯定的是,使用修饰符进行更新与插入文档非常不同。 tomRedox 确实用使用修饰符进行更新的最佳方法回答了他自己的问题。我回答的重点是表明它可以通过另一种方式实现,并展示您如何将 autoform 与 Validated-methods 一起使用。我不确定其他人,但我一直在努力寻找有关如何使用经过验证的方法的信息。我认为添加一种替代方法会很有用。
      猜你喜欢
      • 2015-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 2017-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多