SilverStripe-当一个管理员模型被赋予新条目时,更新另一个



在SilverStripe中,我有两个管理模型:服务和位置。位置是一个位置列表。服务是这些地点可以提供的服务的列表。但是,只有某些地方可以提供某些服务。我想做的是,每当添加新的位置(或者如果删除或重命名了一个位置)时,我都想将其添加到每个服务下的复选框字段中(这样,内容管理器就可以随时轻松地控制在哪里提供哪些服务)。

以下是服务数据对象代码(注意:我还没有在复选框字段中添加):

class Services extends DataObject {
    private static $db = array(
        'Name' => 'varchar',
    );
    public static $summary_fields = array(
        'Name' => 'Title',
    );
}

这是位置数据对象代码:

class Locations extends DataObject {
    private static $db = array(
        'Name' => 'varchar',
        'AcceptingAppointments' => 'boolean',
    );
    public static $summary_fields = array(
        'Name' => 'Title',
        'AcceptingAppointments' => 'Accepting Appointments?',
    );
    public function AcceptingAppointments() {
        return ($this->AcceptingAppointments==true ? 'Yes':'No');
    }
}

到目前为止一切都很好。我可以添加、编辑和删除位置和服务。然而,我不知道如何对服务进行编码,以便每当内容管理器添加、删除或重命名位置条目时,每个服务都会更新所有位置的完整列表。

使用$has_many关系在这方面有效吗?

需要的是ServiceLocation之间的$many_many关系。我们想要一种多对多的关系,因为一个服务可以有很多位置,一个位置可以有很多服务。要了解有关使用$many_many关系的更多信息,请阅读本课程或本文档。

一旦我们定义了$many_many关系,我们就可以添加CheckboxSetField来控制这个关系。

注意,我已经将Locations类重命名为Location,将Services重命名为Service,因为我认为类名应该是单数。

服务

class Service extends DataObject {
    private static $db = array(
        'Name' => 'Varchar'
    );
    private static $belongs_many_many = array(
        'Locations' => 'Location'
    );
    private static $summary_fields = array(
        'Name' => 'Title'
    );
    private static $field_labels = array(
        'Name'
    );
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        if ($this->ID) {
            $fields->addFieldToTab('Root.Locations', CheckboxSetField::create(
                'Locations', 
                'Locations', 
                Location::get()->map()
            ));
        }
        return $fields;
    }
}

Location上,我们将$belongs_many_many关系添加回Service,这样我们就可以在双方控制这种关系。

位置

class Location extends DataObject {
    private static $db = array(
        'Name' => 'Varchar',
        'AcceptingAppointments' => 'Boolean'
    );
    private static $many_many = array(
        'Services' => 'Service'
    );
    private static $summary_fields = array(
        'Name',
        'AcceptingAppointmentsNice'
    );
    private static $field_labels = array(
        'Name' => 'Title',
        'AcceptingAppointmentsNice' => 'Accepting Appointments?'
    );
    public function AcceptingAppointmentsNice() {
        return $this->AcceptingAppointments ? 'Yes' : 'No';
    }
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        if ($this->ID) {
            $fields->addFieldToTab('Root.Services', CheckboxSetField::create(
                'Services', 
                'Services', 
                Service::get()->map()
            ));
        }
        return $fields;
    }
}

CCD_ 15的替代方案是CCD_。ListboxField是一个简洁的下拉多选字段。如果选项列表很长,则会很有用。

class Service extends DataObject {
    // ...
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        if ($this->ID) {
            $fields->addFieldToTab('Root.Locations', ListboxField::create(
                'Locations', 
                'Locations', 
                Location::get()->map('ID', 'Name')->toArray(),
                array(),
                null,
                true
            ));
        }
        return $fields;
    }
}

另外请注意,$summary_fields必须声明为private变量,而不是public变量。

相关内容

最新更新