【发布时间】:2015-04-14 17:22:02
【问题描述】:
我想在 cakePHP 3.0 中制作这个教程http://miftyisbored.com/complete-tutorial-habtm-relationships-cakephp/
我有 3 个表:食谱、配料和配料_食谱。
制作食谱时,我想选择配料。然后我想将 recipe_id 和 ingredients_id 存储在 ingredients_recipes 表中,但没有这样做。我认为我的 RecipesController 有问题。有人可以帮助我或指出正确的方向吗?
问题:
$ingredients = $this->Recipes->Ingredients->find('list', ['limit' => 200]);
// => THIS GIVES ME THE MESSAGE "The recipe could not be saved. Please, try again."
$ingredients = $this->Ingredients->find('list', ['limit' => 200]);
// => THIS GIVES ME THE ERROR "Call to a member function find() on boolean"
当我做 var dump(当使用这个 $this->Recipes->Ingredients->find 时)我得到这个:
array(3) {
["recipe_name"]=> string(4) "Test"
["recipe_description"]=> string(4) "Test"
["Recipe"]=> array(1) {
["Ingredient"]=> array(1) { [0]=> string(1) "1" }
}
}
表格:
CREATE TABLE `recipes` (
`recipe_id` int(11) NOT NULL auto_increment,
`recipe_name` varchar(255) NOT NULL,
`recipe_description` text NOT NULL,
PRIMARY KEY (`recipe_id`)
);
CREATE TABLE `ingredients` (
`ingredient_id` int(11) NOT NULL auto_increment,
`ingredient_name` varchar(255) NOT NULL,
`ingredient_description` text NOT NULL,
PRIMARY KEY (`ingredient_id`)
);
CREATE TABLE `ingredients_recipes` (
`ingredient_id` int(11) NOT NULL,
`recipe_id` int(11) NOT NULL,
PRIMARY KEY (`ingredient_id`,`recipe_id`)
);
下面是我的代码:
模型>实体:
食谱
class Recipe extends Entity
{
protected $_accessible = [
'recipe_id' => true,
'recipe_name' => true,
'recipe_description' => true,
];
}
成分
class Ingredient extends Entity
{
protected $_accessible = [
'ingredient_id' => true,
'ingredient_name' => true,
'ingredient_description' => true,
];
}
成分配方
class IngredientsRecipe extends Entity
{
protected $_accessible = [
'ingredient' => true,
'recipe' => true,
];
}
模型>表:
食谱表
class RecipesTable extends Table
{
public function initialize(array $config)
{
$this->table('recipes');
$this->displayField('recipe_name');
$this->primaryKey('recipe_id');
$this->belongsTo('Recipes', [
'foreignKey' => 'recipe_id',
'joinType' => 'INNER'
]);
$this->belongsToMany('Ingredients', [
'className' => 'Ingredients',
'joinTable' => 'ingredients_recipes',
'foreignKey' => 'recipe_id',
'targetForeignKey' => 'ingredient_id'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->requirePresence('recipe_name', 'create')
->notEmpty('recipe_name')
->requirePresence('recipe_description', 'create')
->notEmpty('recipe_description')
->requirePresence('Ingredients', 'create')
->notEmpty('Ingredients');
return $validator;
}
}
成分表
class IngredientsTable extends Table
{
public function initialize(array $config)
{
$this->table('ingredients');
$this->displayField('ingredient_name');
$this->primaryKey('ingredient_id');
$this->belongsTo('Ingredients', [
'foreignKey' => 'ingredient_id',
'joinType' => 'INNER'
]);
$this->belongsToMany('Recipies', [
'className' => 'Recipies',
'joinTable' => 'ingredients_recipes',
'foreignKey' => 'ingredient_id',
'targetForeignKey' => 'recipe_id'
]);
}
}
成分食谱表
class IngredientsRecipesTable extends Table
{
public function initialize(array $config)
{
$this->table('ingredients_recipes');
$this->displayField('recipe_id');
$this->primaryKey(['recipe_id', 'ingredient_id']);
$this->belongsTo('Recipies', [
'foreignKey' => 'recipe_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Ingredients', [
'foreignKey' => 'ingredient_id',
'joinType' => 'INNER'
]);
}
控制器:
食谱控制器
public function add()
{
$recipe = $this->Recipes->newEntity();
if ($this->request->is('post')) {
$recipe = $this->Recipes->patchEntity($recipe, $this->request->data);
// var_dump($this->request->data);
if ($this->Recipes->save($recipe)){
$this->Flash->success('The recipe has been saved.');
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error('The recipe could not be saved. Please, try again.');
}
}
$recipes = $this->Recipes->find('list', ['limit' => 200]);
$ingredients = $this->Recipes->Ingredients->find('list', ['limit' => 200]);
// => THIS GIVES ME THE MESSAGE "The recipe could not be saved. Please, try again."
$ingredients = $this->Ingredients->find('list', ['limit' => 200]);
// => THIS GIVES ME THE ERROR "Call to a member function find() on boolean"
$this->set(compact('recipe', 'recipes', 'ingredients'));
$this->set('_serialize', ['recipe']);
}
模板>食谱
add.ctp
<?= $this->Form->create($recipe); ?>
<fieldset>
<legend><?= __('Add Recipe') ?></legend>
<?php
echo $this->Form->input('recipe_name', array(
'label' => 'Name'
)
);
echo $this->Form->input('recipe_description', array(
'label' => 'Description'
)
);
echo $this->Form->input('Recipes.Ingredients', ['multiple'=>true]);
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
【问题讨论】:
-
需要注意的一点是食谱表你有'recipe_id'而不是
id。您的recipes表应包含id、name、description等列。如果它们已经在 DB 中进行了这样的设置,那么您需要修复您的代码以反映这一点。看看 CakePHP 标准:book.cakephp.org/3.0/en/contributing/… -
我也没有注意到这是 CakePHP 2 的教程。CakePHP 书中有几个教程是 3.0 示例,即博客和书签教程。
-
是的,我知道本教程适用于 cakePHP 2.0,但我想在 cakePHP 3.0 中重新制作本教程
-
好吧.. 好吧。我会说,在服务器上运行您的代码并返回错误。到时候这里应该有人可以帮助你。或者更好的是,根据 CakePHP 的约定正确创建数据库表(请参阅文档),使用 bin/cake bake all Recipes 等并查看您的代码....然后添加您需要的其他内容。
标签: php mysql cakephp many-to-many has-and-belongs-to-many