2016-05-30 1 views
2

単純なhas_one関係を持つ2つのオブジェクトを持つ標準ModelAdminを使用する。私はMyDataObjectを編集中に "Add HasManyDataObject"をクリックした後、関連するオブジェクトにアクセスしたいと思います。私が満足していない本当のハックが含まれていますが、動作します。もう1つのハックはURLからIDを奪い取ることです。両方ともが悪いです。編集フォームに保存する前に関連するクラスインスタンスを取得する強力なメソッド

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

私は何かがこのように動作するように期待...

$myDataObject = $this->MyDataObject(); 

...しかし、ノー。

面倒なことは、オブジェクトが編集フォームの読み取り専用フィールドとして指定されていることです。何とか利用可能でなければなりません!

すべての回答が非常に高く評価されました。

+0

...追加と、次の機能は、「親」オブジェクトを返す使用してありませんか?既存のアイテムを$ has_oneとして追加するにはhttps://github.com/briceburg/silverstripe-pickerfield/blob/master/code/HasOnePickerField.php – wmk

+0

ありがとうございます。 – Barry

答えて

0

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

私はこの時間と時間をもう一度見てきました。あなたが見つけたように、プライマリモデルオブジェクトにアクセスできない理由は、セカンダリモデルが保存されるまで、はこれらのモデルのDBテーブルの間には関係がありませんです。あなたがまだDataObjectのサブクラスインスタンスを作成するために保存されていない場合、SilverStripeはモデルのインスタンスを与えることはできません。

回避策は、プライマリモデルのIDのURLを「スクレイプ」し、その状態をどこかに保存することです。セッションまたはHTML5 localStorage現在のコントローラーのSS_HTTPRequestインスタンスにgetURL()を使用して照会することによって、そのIDを引き出す方法が少し少なくなります。 params()からいくらかのマイレージを取得することもできます。アクセス権があるかどうかを確認するためにダンプしてください。フレームワークがあなたのハッキングを助けるようにしましょう:-)

幸運。

+0

あなたの答えをありがとう、それは "関係がありません"と言っているSSがどのようにオブジェクトをリンクすることができるか説明することができます... "親"オブジェクトを決定する堅牢な方法がない場合...確かにSSより強固な別の方法を使用する必要がありますか? – Barry

0

様々なソリューションと同じ問題を扱ってここに古いフォーラムのスレッドがあります:いくつかはGridFieldEditForm経由ParentIDを注入し、いくつかは、現在のControllerのparamsからそれを得る http://www.silverstripe.org/community/forums/data-model-questions/show/21517?start=8

が。新しいhas_manyのコンポーネントを作成するためにgridfieldコンポーネントは

+0

あなたの答えを受け入れるには、セッションやURLのスクレイピングを使用するよりも良い方法だと思いますが、フォーラムのコードを明確な使い方で追加できますか? SSがそれをどうやってやっているのだろうか – Barry

関連する問題