2015-11-17 42 views
2

在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關係工作嗎?

回答

3

需要的是ServiceLocation之間的$many_many關係。我們希望有多對多的關係,因爲服務可以有很多地點,而且一個地點可以有很多服務。要了解有關使用$many_many關係的更多信息,請參閱this lessonthis documentation

一旦我們有一個$many_many關係定義,我們可以添加一個CheckboxSetField來控制這種關係。

注意,我已經改名爲LocationsLocationServicesService因爲我認爲類的名稱應爲單數。

服務

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; 
    } 
} 

CheckboxSetField另外也可以將ListboxFieldListboxField是一個整齊的下拉多選字段。如果選項列表非常長,這很有用。

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變量。

+1

哇......那很完美!非常感謝你的回答 - 它回答了我的確切問題,證實了我的一些想法,並且似乎已經按照我的意願設置了一切。 –

相關問題