2017-02-25 3 views
0

DataObjectを拡張し、単にTitle、Desc、およびImageを持つクラスを作成したいとします。1つの汎用データオブジェクトとhas_many関係を持つ多くのデータオブジェクト

class ImageBlock extends DataObject 
{ 
    private static $db = [ 
     'Title' => 'Varchar(50)', 
     'Description' => 'Varchar(255)' 
    ]; 

    private static $has_one = [ 
     'Image' => 'Image' 
    ]; 
} 

これは、フロントエンドに表示するための一般的なタイルで、複数のページで、複数のデータオブジェクトの中に示すことができました。与えられたページまたはDOは、これらの多くを持つことができます。明確にするために、これは単なるページ用ではありません。私は地域を有するこれらのImageBlocksのそれにhas_manyをDO:

class TourRegion extends \DataObject 
{ 
    private static $db = [ 
     'RegionName' => 'Varchar(50)', 
     'RegionSlug' => 'Varchar(50)', 
     'RegionIntro' => 'Varchar(255)', 
     'RegionDescription' => 'Text', 
    ]; 

    private static $has_many = [ 
     'RegionHeroImages' => 'TourHeroImage', 
     'MainAttractions' => 'ImageBlock' 
    ]; 

    .... 

私の質問はのDataObjectにhas_manyのは、そのDataObjectの上にhas_one関係を必要とする、です。 has_one関係は2つ以上の可能なクラスである可能性があるので、このリファレンスを作成するにはどうすればよいですか?

[User Error] Uncaught Exception: No has_one found on class 'ImageBlock', the has_many relation from 'TourRegion' to 'ImageBlock' requires a has_one on 'ImageBlock'

が、私は同じエラーを取得:

class ImageBlock extends DataObject 
{ 
    private static $db = [ 
     'Title' => 'Varchar(50)', 
     'Description' => 'Varchar(255)' 
    ]; 

    private static $has_one = [ 
     'Image' => 'Image', 
     'ParentObject' => 'DataObject' 
    ]; 
} 

しかし、私はこのエラーを取得する:

は、私は次のようにこれらのオブジェクトのシェア(のDataObjectが)という最低の共通クラスにhas_oneのを追加しようとしています私はImageBlockでhas_oneを省略しようとします。それは質問をする。なぜImageやFileのようなDataObjectsにhas_manyリレーションシップを追加することができますか?

Silverstripeには、一般的で再利用可能なhas_many関連オブジェクトを持つことはできないようです。そして、このImageBlockを持つ必要があるすべてのクラスは、has_one参照を追加する唯一の目的のためにクラスを複製する必要があります。

答えて

2

ご質問の最後にお答えするには、has_manyは意味がありません。これは、データベースに構造的な変更を加えません。それ以外のところでhas_oneを探す親のDataObjectにマジックメソッドを追加するだけです。 has_manyを定義するのは、ゲッターを書く時間を節約するために、基本的に便宜上のものです。あなたが私には理にかなっている親、で関係を定義するために探しているなら

、私はそれが何の相互関係を必要としないようmany_manyとして、(それはbelongs_many_manyにより往復動することができることを行うだろうが、それは単に便利ですメソッドもあります)。

一貫性とわかりやすさのために、私はmany_many => ImageBlockを必要なものに注入する拡張を作成します。

+0

[SilverStripeのORM関係の図](http://silverstrip.es/blog/diagram-of-relationships-in-silverstripe)です。 – wmk

+0

ありがとうございます。あなたはあなたの最後の文章であなたのメナを説明するか、リンクすることができますか?私は本当にここで答えの多くを見ていないよ。これまでのところ、Silverstripeでは一般的な再利用可能なオブジェクトを持つことはできません。私はこれを行う方法を見ることができる唯一の方法は、基本オブジェクトを持って、それを使用してそれを使用する各親のために特定のオブジェクトを拡張するためにそれを使用します。これらのクラスにあるものはすべてhas_one関係です。 – Aaryn

+0

再利用可能で一般的なものが必要な場合は、おそらく 'has_many'が最良の方法ではありません。しかし、これを行う1つの方法は、一般的な 'ImageBlockHolder'(例えば、抽象クラス)を作成することですが、それは継承チェーンを課すより垂直的なアプローチです。それをやりたければ、ここに例があります(http://sspaste.com/paste/show/58b281b17ea91)。 上記で説明したように、「many_many」を使用したより水平なアプローチ(http://sspaste.com/paste/show/58b2828816cab) – UncleCheese

関連する問題