def mutate(root, args, context, info):
        options = args.get('options')
        if options is not None:
            cls = models.SelectField
        else:
            cls = models.TextField

        require_cls_permission(CrudPermissions.CREATE, cls, context)
        discussion_id = context.matchdict['discussion_id']
        with cls.default_db.no_autoflush as db:
            title_entries = args.get('title_entries')
            if len(title_entries) == 0:
                raise Exception(
                    'TextField titleEntries needs at least one entry')

            title_langstring = langstring_from_input_entries(title_entries)
            saobj = cls(discussion_id=discussion_id,
                        title=title_langstring,
                        order=args.get('order'),
                        required=args.get('required'))

            if options is not None:
                for option in options:
                    label_ls = langstring_from_input_entries(
                        option['label_entries'])
                    order = option['order']
                    saobj.options.append(
                        models.SelectFieldOption(label=label_ls, order=order))

            db.add(saobj)
            db.flush()

        return CreateTextField(field=saobj)
    def mutate(root, args, context, info):
        options = args.get('options')
        if options is not None:
            cls = models.SelectField
        else:
            cls = models.TextField

        field_id = args.get('id')
        field_id = int(Node.from_global_id(field_id)[1])
        field = cls.get(field_id)
        require_instance_permission(CrudPermissions.UPDATE, field, context)
        with cls.default_db.no_autoflush as db:
            title_entries = args.get('title_entries')
            if len(title_entries) == 0:
                raise Exception('field titleEntries needs at least one entry')

            update_langstring_from_input_entries(field, 'title', title_entries)
            field.order = args['order']
            field.required = args['required']
            field.hidden = args['hidden']

            if options is not None:
                existing_options = {
                    option.id: option
                    for option in field.options
                }
                updated_options = set()
                for option_input in options:
                    if not option_input.get('id', '-1').startswith('-'):
                        # update the option
                        id_ = int(Node.from_global_id(option_input['id'])[1])
                        updated_options.add(id_)
                        option = models.SelectFieldOption.get(id_)
                        update_langstring_from_input_entries(
                            option, 'label', option_input['label_entries'])
                        option.order = option_input['order']
                    else:
                        # create the option
                        label_ls = langstring_from_input_entries(
                            option_input.get('label_entries', None))
                        order = option_input.get('order')
                        field.options.append(
                            models.SelectFieldOption(label=label_ls,
                                                     order=order))

                # remove options that are not in options input
                for option_id in set(
                        existing_options.keys()).difference(updated_options):
                    db.delete(existing_options[option_id])

            db.flush()

        return UpdateTextField(field=field)