2016-05-30 4 views
2

Verwenden eines Standard ModelAdmin mit zwei Objekten mit einer einfachen has_one-Beziehung. Ich möchte auf das entsprechende Objekt zugreifen, nachdem ich während der Bearbeitung eines MyDataObject auf "Add HasManyDataObject" geklickt habe. Enthalten ist ein echter Hack, mit dem ich nicht zufrieden bin, aber funktioniert. Ein weiterer Hack soll die ID aus der URL herauskratzen. Beide nicht gut.Robuste Methode zum Abrufen der zugehörigen Klasseninstanz vor dem Speichern im Bearbeitungsformular

class MyModelAdmin extends ModelAdmin { 
    static $managed_models = array('MyDataObject'); 
    static $url_segment = 'mymodeladmin'; 
    static $menu_title = 'MyModelAdmin'; 
    static $model_importers = array(); 
} 

class MyDataObject extends DataObject { 
    private static $db = array('Name' => 'Varchar(255)'); 
    private static $has_many = array('HasManyDataObjects' => 'HasManyDataObject'); 

    function getCMSFields() { 
     $fields = parent::getCMSFields(); 

    Session::set('MyDataObjectID',$this->ID); 
    Session::save(); 

     return $fields; 
    } 
} 

class HasManyDataObject extends DataObject { 
    private static $db = array('Name' => 'Varchar(255)'); 
    private static $has_one = array('MyDataObject' => 'MyDataObject'); 

    function getCMSFields() { 
     $fields = parent::getCMSFields(); 

     $myDataObject = MyDataObject::get()->ByID(Session::get('MyDataObjectID')); 

     return $fields; 
    } 
} 

Ich würde erwarten so etwas zu arbeiten ...

$myDataObject = $this->MyDataObject(); 

... aber nein.

Die frustrierende Sache ist, dass es das Objekt als schreibgeschütztes Feld im Bearbeitungsformular angibt, also muss es irgendwie verfügbar sein!

Alle Antworten sehr geschätzt.

+0

Gibt es nicht eine gridfield Komponente eine neue has_many Komponente zu schaffen? Um ein bestehendes Element als $ has_one hinzuzufügen gibt es https://github.com/briceburg/silverstripe-pickerfield/blob/master/code/HasOnePickerField.php – wmk

+0

hey @wmk wenn es da ist - dann antworte und ich werde es akzeptieren :) – Barry

Antwort

0

Hinzufügen und verwenden Sie die folgende Funktion die „Eltern“ Objekt zurückgibt ...

public static function GetParentObject($class) { 
    $obj = null; 

    $controller = Controller::curr(); 
    if ($controller->request->Param('ModelClass') == $class) 
     $obj = $class::get()->ByID($controller->request->Param('ID')); 

    if ($obj) 
     return $obj; 

    $url = $_SERVER['REQUEST_URI']; 
    $start = $class.'/item/'; 
    $end = '/'; 
    $startpos = strpos($url,$start); 
    $id = null; 
    if ($startpos != false) { 
     $startpos += strlen($start); 
     $endpos = strpos($url,$end,$startpos); 
     $id = substr($url,$startpos,$endpos - $startpos); 
    } 

    return $class::get()->ByID($id); 
} 
3

Ich bin immer wieder auf dieses Mal gestoßen. Wie Sie herausgefunden haben, liegt der Grund, warum Sie nicht auf das primäre Modellobjekt zugreifen können, darin, dass keine Beziehung zwischen den einzelnen DB-Tabellen dieser Modelle vorhanden ist, bis das sekundäre Modell gespeichert ist. Ergo, SilverStripe kann Ihnen die Instanz des Modells nicht geben, wenn sie noch nicht gespeichert wurde, um daraus eine DataObject Unterklasseninstanz zu erstellen.

Die Problemumgehung ist, wie Sie festgestellt haben, die URL für die ID des primären Modells zu "kratzen" und diesen Zustand irgendwo zu speichern, z. eine Sitzung oder HTML5 localStorage. Es gibt etwas weniger hacky Wege, diese ID heraus zu ziehen, indem Sie die SS_HTTPRequest Instanz des aktuellen Controllers mit getURL() abfragen. Sie können auch einige Kilometer aus params() abrufen - dumpen Sie aus, um zu sehen, auf was Sie Zugriff haben. Lassen Sie das Framework Ihnen in Ihren Hacks helfen :-)

Viel Glück.

+0

Danke für Ihre Antwort, aber es sagt "es gibt keine Beziehung" können Sie erklären, wie SS die Objekte dann verknüpfen kann ... wenn es keine robuste Möglichkeit gibt, das "Eltern" -Objekt zu bestimmen ... sicherlich SS muss eine andere Methode verwendet werden, die robuster ist? – Barry

0

Es gibt einen alten Forum-Thread hier, die mit verschiedenen Lösungen mit dem gleichen Problem beschäftigt: http://www.silverstripe.org/community/forums/data-model-questions/show/21517?start=8

Einige injizieren, um die ParentID über die GridFieldEditForm und einige bekommen es aus dem aktuellen Controller params.

+0

Nun, das scheint eine bessere Methode zu sein, als die Sitzung oder das Scraping der URL zu benutzen, damit ich deine Antwort akzeptieren kann. Bitte füge den Code aus dem Forum in einer klar verwendbaren Weise hinzu (gemäß SO Richtlinien) und ich denke ich damit bin ich einverstanden ... so muss es sein, wie die SS es innen macht – Barry

Verwandte Themen