两个连接表。怎么管理?

时间:2014-04-02 21:26:04

标签: silverstripe

我在SS3项目中有这种关系:

  • 餐厅many_many美食
  • 烹饪many_many SubCuisine

看起来很简单,但我似乎找不到任何方法来管理它。尝试过GridField和Listbox。这可能是SilverStripe的限制吗?

感谢任何线索! 威尔逊

2 个答案:

答案 0 :(得分:2)

在我们对IRC的谈话之后,我们提出了以下替代解决方案,我将在此处发布以供记录。

此解决方案与原始答案类似,但不同之处在于,还有一个额外的对象可以处理RestaurantCuisine之间的关系。

档案:Restaurant.php

/**
 * @method ManyManyList RestaurantCuisines
 */
class Restaurant extends Page {
    private static $many_many = array(
        'RestaurantCuisines' => 'RestaurantCuisine',
    );

    /**
     * @return FieldList
     */
    public function getCMSFields() {
        $return = parent::getCMSFields();
        $return->addFieldToTab('Root', Tab::create('Cuisines', 'The Cuisines'));
        $return->addFieldToTab(
            'Root.Cuisines',
            GridField::create(
                'RestaurantCuisines',
                'The Cuisines this Restaurant offers',
                $this->RestaurantCuisines(),
                GridFieldConfig_RecordEditor::create()
            )
        );
        return $return;
    }
}

class Restaurant_Controller extends Page_Controller {
}

档案:RestaurantCuisine.php

/**
 * @property int CuisineID
 * @method Cuisine Cuisine
 * @method ManyManyList SubCuisines
 */
class RestaurantCuisine extends DataObject {
    private static $has_one = array(
        'Cuisine' => 'Cuisine',
    );
    private static $many_many = array(
        'SubCuisines' => 'SubCuisine',
    );
    private static $summary_fields = array(
        'getTitle' => 'Title'
    );
    public function getCMSFields() {
        if ($this->isInDB()) {
            $grid = GridField::create(
                'SubCuisines',
                'The Sub Cuisines of this Cuisines',
                $this->SubCuisines(),
                GridFieldConfig_RelationEditor::create()
            );
        } else {
            // because this record is not saved to the DB yet, we have no ID, without ID there can be no many_many relation
            $grid = ReadonlyField::create('SubCuisines', '', 'Sub Cuisines can be added after creating');
        }
        return FieldList::create(array(
            DropdownField::create('CuisineID', 'Select a Cuisine', Cuisine::get()->map()),
            $grid
        ));
    }
    /**
     * overwrite getTitle and return title of Cuisine to have a nice text to display instead of the ID when displaying the save message
     */
    public function getTitle() {
        return $this->Cuisine() && $this->Cuisine()->exists() ? $this->Cuisine()->Title : parent::getTitle();
    }
}

文件:Cuisine.php

/**
 * @property string Title
 */
class Cuisine extends DataObject {
    private static $db = array(
        'Title' => 'Varchar(255)',
    );

    /**
     * @return FieldList
     */
    public function getCMSFields() {
        return FieldList::create(array(
            TextField::create('Title', 'Name of Cuisine'),
        ));
    }
}

文件:SubCuisine.php

/**
 * @property string Title
 */
class SubCuisine extends DataObject {
    private static $db = array(
        'Title' => 'Varchar(255)',
    );

    /**
     * @return FieldList
     */
    public function getCMSFields() {
        return FieldList::create(array(
            TextField::create('Title', 'Name of Cuisine'),
        ));
    }
}

答案 1 :(得分:1)

GridField是管理这种数据结构的完美工具,我每天都会这样做。

由于你的话题,我觉得有必要提一下:它不加入这里(好吧,是的,ORM加入了,但不是餐厅和菜肴和SubCuisine)。
以下示例将执行以下操作:

  • 在单个Restaurant上,它会显示Cuisine个列表(GridField),您可以在其中创建新列表或附加现有列表。
  • 在单个Cuisine上,它会显示SubCuisine个列表(GridField),您可以在其中创建新列表或附加现有列表。

(我假设RestaurantPage,但如果它是正常的DataObject

,它也能正常工作

档案Restaurant.php

/**
 * @method ManyManyList Cuisines
 */
class Restaurant extends Page {
    private static $many_many = array(
        'Cuisines' => 'Cuisine',
    );

    /**
     * @return FieldList
     */
    public function getCMSFields() {
        $return = parent::getCMSFields();
        $return->addFieldToTab('Root', Tab::create('Cuisines', 'The Cuisines'));
        $return->addFieldToTab(
            'Root.Cuisines',
            GridField::create(
                'Cuisines',
                'The Cuisines this Restaurant offers',
                $this->Cuisines(),
                GridFieldConfig_RelationEditor::create()
            )
        );
        return $return;
    }
}

class Restaurant_Controller extends Page_Controller {
}

档案Cuisine.php

/**
 * @property string Title
 * @method ManyManyList SubCuisines
 */
class Cuisine extends DataObject {
    private static $db = array(
        'Title' => 'Varchar(255)',
    );
    private static $many_many = array(
        'SubCuisines' => 'SubCuisine',
    );

    /**
     * @return FieldList
     */
    public function getCMSFields() {
        if ($this->isInDB()) {
            $grid = GridField::create(
                'SubCuisines',
                'The Sub Cuisines of this Cuisines',
                $this->SubCuisines(),
                GridFieldConfig_RelationEditor::create()
            );
        } else {
            // because this record is not saved to the DB yet, we have no ID, without ID there can be no many_many relation
            $grid = ReadonlyField::create('SubCuisines', '', 'Sub Cuisines can be added after creating');
        }
        return FieldList::create(array(
            TextField::create('Title', 'Name of Cuisine'),
            $grid,
        ));
    }
}

档案SubCuisine.php

/**
 * @property string Title
 */
class SubCuisine extends DataObject {
    private static $db = array(
        'Title' => 'Varchar(255)',
    );

    /**
     * @return FieldList
     */
    public function getCMSFields() {
        return FieldList::create(array(
            TextField::create('Title', 'Name of Cuisine'),
        ));
    }
}

文件Restaurant.ss(模板):

<h1>Restaurant: $Title</h1>
<% if $Cuisines %>
    <h2>Cuisines</h2>
    <ol>
        <% loop $Cuisines %>
            <li>
                <h3>$Title</h3>
                <% if $SubCuisines %>
                    <h4>Sub Cuisines:</h4>
                    <ul>
                        <% loop $SubCuisines %>
                            <li>
                                <h5>$Title</h5>
                            </li>
                        <% end_loop %>
                    </ul>
                <% end_if %>
            </li>
        <% end_loop %>
    </ol>
<% end_if %>