1

我将“createdBy”字段添加到模型中,但它允许管理员选择所有用户作为“createdBy”用户。我希望这个字段自动填充当前登录的管理员并且似乎无法让它工作。

理想情况下,这根本不会出现在 UI 中,而只是在保存用户时存储。

User.add({
    name: { type: Types.Name, required: true, index: true },
    email: { type: Types.Email, initial: true, required: true, index: true },
    company: { type: String, required: true, index: true, initial: true },
    phone: { type: String, required: true, index: true, initial: true },
    password: { type: Types.Password, initial: true, required: true },
    createdBy: { type: Types.Relationship, initial:true, required:true, ref: 'User' },
    createdAt: { type: Date, default: Date.now }
    }, 'Permissions', {
      level : { type: Types.Select, numeric: true, options: [{ value: 1, label: 'User'   }, {     value: 2, label: 'Group Administrator' }, { value: 3, label: 'System Administrator' }] }
    },
    'Screening', {
      rooms : { type: Types.Select, numeric: true, options: [{ value: 1, label: 'Screening room 1' }, { value: 2, label: 'Screening room 2' }, { value: 3, label: 'Screening room 3' }] }
});
4

2 回答 2

2

虽然您的实现功能正常,但许多 Keystone 开发人员(包括我自己)对user.id通过POST. 当您说目前在 Keystone 中没有这样做的好方法时,您也是正确的。

我的解决方案是在 Keystone 本身上实现该功能。我添加了一个可选的元模式,我称之为audit meta. 这会向List(createdByupdatedBy) 添加两个字段,我UpdateHandler()使用req.user. 这样就不需要user._id通过 POST 发送。

要使用它,您只需List.addPattern('audit meta');在定义列表后添加,就像您使用standard meta. 我的实现audit meta还添加了standard meta字段,因此无需同时使用两者。

为了实现这一点,我对 Keystone 进行了以下更改

首先,lib\list.js我在方法中添加了以下代码(以 为前缀+addPatern()

List.prototype.addPattern = function(pattern) {

    switch (pattern) {
        ...

+       case 'audit meta':
+           var userModel = keystone.get('user model');
+
+           if(!this.schema.path('createdOn') && !this.schema.path('updatedOn')) {
+               this.addPattern('standard meta');
+           }
+
+           if (userModel) {
+               this.add({
+                   createdBy: { type: Field.Types.Relationship, ref: userModel, hidden: true, index: true },
+                   updatedBy: { type: Field.Types.Relationship, ref: userModel, hidden: true, index: true }
+               });
+               this.map('createdBy', 'createdBy');
+               this.map('modifiedBy', 'updatedBy');
+           }
+       break;
+
    }

    return this;

然后在lib/updateHandler.js我将以下代码添加到UpdateHandler.prototype.process(),就在progress()方法结束时调用之前。

+   // check for audit meta fields (mapped to createdBy/modifiedBy)
+   if (this.list.mappings.createdBy && this.item.isNew) {
+       this.item.set(this.list.mappings.createdBy, this.user._id);
+   }
+   if (this.list.mappings.modifiedBy) {
+       this.item.set(this.list.mappings.modifiedBy, this.user._id);
+   }

早些时候,我向 Keystone 提交了一个拉取请求 ( https://github.com/JedWatson/keystone/pull/490 ),其中包括对我的实现的详细解释。所以,如果你迫切需要这个,你可以随时 fork 一份 Keystone 并合并我的 PR。

于 2014-07-25T01:21:35.867 回答
1

显然没有很好的方法可以做到这一点,但我确实想出了一个解决方法,通过创建一个自定义隐藏输入字段来使用别人的想法。这并不理想,但适用于这个项目。createdBy 的默认值只是为了让我可以将其设为必填字段,但它填充在表单中的翡翠模板中,而不是该输入类型的初始翡翠模板。

User.add({
  name: { type: Types.Name, required: true, index: true },
  email: { type: Types.Email, initial: true, required: true, index: true },
  company: { type: String, required: true, index: true, initial: true },
  phone: { type: String, required: true, index: true, initial: true },
  password: { type: Types.Password, initial: true, required: true },
  createdBy: { type: Types.Admin, required: true, initial: true, default: 'createdBy' },
  createdAt: { type: Types.Hidden, default: Date.now }
}, 'Permissions', {
  level : { type: Types.Select, numeric: true, options: [{ value: 1, label: 'User' }, {     value: 2, label: 'Group Administrator' }, { value: 3, label: 'System Administrator' }] }
},Screening', {
  rooms : { type: Types.Select, numeric: true, options: [{ value: 1, label: 'Screening room 1' }, { value: 2, label: 'Screening room 2' }, { value: 3, label: 'Screening room 3' }] }
});

然后自定义字段类型就像这样,只需为表单和初始创建一个。同时创建 fieldTypes/admin.js 并更新 fieldTypes.index.js

输入 admin/form.jade

.field(class='type-' + field.type, data-field-type=field.type, data-field-path=field.path, data-field-collapse=field.collapse ? 'true' : false, data-field-depends-on=field.dependsOn, data-field-noedit=field.noedit ? 'true' : 'false')
- var value = field.format(item)
.field-ui(class='width-' + field.width)
    if field.noedit
        .field-value= user._id
    else
        input(type='hidden', name=field.path, value=user._id, autocomplete='off').form-control
    if field.note
        .field-note!= field.note
于 2014-07-24T23:06:52.270 回答