在与多个数据对象共享的配置 yaml 中定义的枚举列表

Enum list defined in a config yaml shared with multiple DataObjects

我有一些 DataObjects 具有与之关联的价格等级。我可以在另一个 DataObject 中建立这种关系,但是这些层不会改变,我认为最好的方法是在 config.yml.

中定义它们

理想情况下,我想将 DataObject 定义为:

private static $db = array(
    'Price' => 'Enum(array("Tier 1", "Tier 2"))'
)

但是我想不出在 SilverStripe 中正确执行此操作的方法,它具有像 yaml 这样的单点维护。我还想过将它设为 Varchar 并在设置它之前检查以确保它在数组中,但是这不允许通过枚举填充列表等操作(我猜无论如何都应该调用配置).我也可以只写出数组,但是至少有两个地方很难维护。

要实现我正在尝试实现的目标的最佳方法是什么,即多个对象在一个位置引用一个数组集?

我不是 100% 确定你在问什么,但如果它像标题一样并且你在问你是否可以在 YAML 中定义 Enum DB 字段值,是的 - 你可以:

MyDataObject:
  db:
    Price: Enum("Tier 1,Tier 2")

不能做的是从其他配置源(包括私有静态)向枚举添加更多值,因为枚举值被视为字符串文字而不是一个 YAML 数组。


如果您的问题是 "Can I define a common configuration for $db and use it for multiple DataObjects",那么 YAML 方法(一般配置)将不起作用,因为配置值绑定到 class 并且在过程中比DataObject::database_fields 告诉数据库模式要做什么。

当然,您可以在配置 yml 中添加和覆盖 $db 键,例如:

MyDataObject:
  db:
    Price: "Enum('Tier 1,Tier 2,Tier 3', 'Tier 3')"

请务必使用 right syntax for Enum,使用旧的逗号分隔语法更容易。在上面的示例中,"Tier 3" 是默认值。

在 yml 中定义它可能会在您使用脚手架时破坏顺序,尚未对此进行测试。

您也可以考虑使用与简单数据对象的 has_one 关系。您可以在 ModelAdmin 中管理它,以后可能更容易翻译。 QuickAddNew module 也是在下拉字段下方动态添加新 DO 的好帮手。

您可以通过创建 DataExtension 并将其应用到您想要添加字段的所有 DataObject,将相同的数据库字段应用到多个 DataObject。

如其他答案所示,您可以通过多种方式实现这一目标。例如,在我从事的一个项目中,我有类似于以下内容的内容:

// You need to put this into a _config.php. It copies the definition
// of DataObject2.Field2 into DataObject1.Field1.
$cfg = Config::inst();
$db = $cfg->get('DataObject1', 'db');
$db['Field1'] = $cfg->get('DataObject2', 'db')['Field2'];
$db = $config->update('DataObject1', 'db', $db);

但在我看来,最优雅的解决方案是定义一个新的 class,例如:

class MyEnum extends Enum
{
    /**
     * Enum values.
     * @config
     */
    private static $values;

    public function __construct($name = null, $default = null)
    {
        parent::__construct($name, $this->config()->get('values'), $default);
    }
}

之后,您可以在纯 YAML 中定义值:

MyEnum:
  values:
    - First
    - Second
    ...