【问题标题】:CakePHP does not use my modelsCakePHP 不使用我的模型
【发布时间】:2014-03-21 12:49:33
【问题描述】:

我有这两个 CakePHP V 2.4.5 模型:

class Owner extends AppModel {
    public $name = 'Owner';
    public $hasMany = array('Car');
}

class Car extends AppModel {
    public $name = 'Car';
    public $belongsTo = array('Owner');
}

在我的控制器中我写道:

var $uses = array('Owner', 'Car');

public function test(){
    $data = array(
        'Owner' => array(
            'name' => 'Me'
        ),
        'Car' => array(
            array('color' => 'red'),
            array('color' => 'blue')
        )
    );
    $this->Owner->saveAssociated($data, array('deep' => true));
}

但是 CakePHP 创建了所有者并忘记创建他的汽车:

1   BEGIN
2   INSERT INTO `test`.`owners` (`name`) VALUES ('Me')
3   COMMIT

这就是我的 ERM 的样子:

为什么 CakePHP 不保存汽车?

【问题讨论】:

  • 你的 dbms 是什么?也许您的表不支持事务。试试saveAssociated($data, array('atomic' => false))(您不需要 deep 选项,因为 Owner id 与 Car 直接关联)
  • 我在 Xampp for Windows 附带的标准配置中使用 MySQL V 5.1.41。
  • 还有什么样的桌子?请参阅上面的编辑。
  • 我刚刚将一个事务交给了 PhpMyAdmin,所以我可以验证 MySQL 让我在一个事务中插入多条记录。它在那里奏效了。使用atomic => false 确实省略了BEGINCOMMIT 语句,但仍然只剩下一个插入所有者的语句。您需要更多信息吗?
  • 我只是对您使用的那种存储引擎感到好奇。但如果你可以进行交易,那么我猜是 InnoDB

标签: php cakephp cakephp-2.4


【解决方案1】:

不可能给出直接有效的答案,因为:问题中的代码没有任何问题。这可能意味着您根本没有运行自己的代码。

鉴于可以给出的唯一答案是建议,对于问题中的示例而言,唯一重要的类是 Owner

检查文件名

model conventions 是:

模型类 OptionValue 可以在名为 OptionValue.php 的文件中找到

到目前为止,错误命名的模型文件是“为什么我的模型逻辑没有被执行”问题的最常见原因。一个陷阱是在模型文件中添加后缀Model.php,模型文件命名是否正确?

在这种情况下,请检查文件 app/Model/Owner.php 是否存在。

验证模型是你的模型

如果您确定模型文件命名正确检查应用正在使用什么

debug(get_class($this->Owner));
########## DEBUG ##########
'Owner'
###########################

如果输出为“AppModel” - 模型文件未加载。 CakePHP 不使用存在的文件的原因很少,其中一个会适用:

  • 文件不存在 - 名称中有错字
  • 应用程序未在您所在的同一目录中查找
  • 应用程序没有打开文件的权限

验证关联是否存在

debug($this->Owner->hasMany);
########## DEBUG ##########
array(
'Car' => array(
    'className' => 'Car',
    'foreignKey' => 'owner_id',
    'conditions' => '',
    'fields' => '',
    'order' => '',
    'limit' => '',
    'offset' => '',
    'dependent' => '',
    'exclusive' => '',
    'finderQuery' => '',
    'counterQuery' => ''
)
)
###########################

如果Car 不在输出中 - 关联没有保存,因为它不存在 - 你需要找出原因。

检查加载了哪些文件

如果有疑问,请检查运行时加载了哪些文件:

debug(get_included_files());
########## DEBUG ##########
array(
    ...
    ...app/Model/Owner.php
    ...
)
###########################

这可能表示正在加载一个不同的文件,这会阻止app/Model/Owner.php被加载。

使用测试来验证发生了什么

您可以使用测试用例来辅助调试,例如:

<?php
App::uses('Owner', 'Model');

class OwnerTest extends CakeTestCase {

    public $fixtures = array(
        'app.car',
        'app.owner',
    );

    public function setUp() {
        parent::setUp();
        $this->Owner = ClassRegistry::init('Owner');
    }

    public function tearDown() {
        unset($this->Owner);
        parent::tearDown();
    }

    public function testCreate() {
        $data = array(
            'Owner' => array(
                'name' => 'Me'
            ),
            'Car' => array(
                array(
                    'Car' => array(
                        'color' => 'red',
                    )
                ),
                array(
                    'color' => 'blue',
                )
            )
        );

        $this->assertSame('Owner', get_class($this->Owner));

        $this->Owner->getDatasource()->getLog();
        $this->Owner->saveAssociated($data);
        $log = $this->Owner->getDatasource()->getLog();
        $expected = array();
        $this->assertSame($expected, $log, 'Look ma, the sql log');
    }
}

应该输出:

-> Console/cake test Test/Case/Model/OwnerTest.php 

Welcome to CakePHP v2.4.5 Console
---------------------------------------------------------------
App : app
Path: /var/www/files.dev/htdocs/app/
---------------------------------------------------------------
CakePHP Test Shell
---------------------------------------------------------------
PHPUnit 3.7.24 by Sebastian Bergmann.

F

Time: 169 ms, Memory: 9.00Mb

There was 1 failure:

1) OwnerTest::testCreate
Look ma, the sql log
Failed asserting that Array (
    'log' => Array (
        0 => Array (
            'query' => 'BEGIN'
            'params' => Array ()
            'affected' => null
            'numRows' => null
            'took' => null
        )
        1 => Array (
            'query' => 'INSERT INTO `test_database_name`.`owners` (`name`) VALUES ('Me')'
            'params' => Array ()
            'affected' => 1
            'numRows' => 1
            'took' => 0.0
        )
        2 => Array (
            'query' => 'INSERT INTO `test_database_name`.`cars` (`color`, `owner_id`) VALUES ('red', 1)'
            'params' => Array ()
            'affected' => 1
            'numRows' => 1
            'took' => 0.0
        )
        3 => Array (
            'query' => 'INSERT INTO `test_database_name`.`cars` (`color`, `owner_id`) VALUES ('blue', 1)'
            'params' => Array ()
            'affected' => 1
            'numRows' => 1
            'took' => 0.0
        )
        4 => Array (
            'query' => 'COMMIT'
            'params' => Array ()
            'affected' => 1
            'numRows' => 1
            'took' => 0.0
        )
    )
    'count' => 9
    'time' => 0.0
) is identical to Array ().

FAILURES!
Tests: 1, Assertions: 2, Failures: 1.
$

请注意,正确地为“我”创建了一个车主,以及两辆汽车 - 每个都链接到“我”的车主记录。

【讨论】:

  • 你猜对了!我的文件被称为 OwnerModel.php 和 CarModel.php,因为我认为惯例有义务这样做。重命名它们后,一切都按预期工作。我什至不需要你的其他调试技巧,但是下次当我遇到此类问题而没有任何错误消息时,我会考虑它们。非常感谢!
  • 很好的回复!如果您在插件中,则可能需要在调用关联时包含 PluginName。例如,我在 Course.php 模型中有 $hasMany。在 $hasMany 调用中,我必须提到带有句点 (.) 的 PluginName 后缀,以使其看起来像 'className' => 'Training.CoursesMembership' 如果我这样做,它会加载 CoursesMembership 模型,否则不会。
【解决方案2】:

我已经测试了您的代码。
它完美无缺。
尝试删除 /tmp/cache 文件夹中的模型缓存
我的结果:

(default) 3 queries took 0 ms   Nr  Query   Error   Affected    Num. rows   Took (ms)
1   BEGIN       0   0   0
2   INSERT INTO `intranet`.`owners` (`name`) VALUES ('Me')      1   1   0
3   INSERT INTO `intranet`.`cars` (`owner_id`, `color`) VALUES (3, 'red')       1   1   0
4   INSERT INTO `intranet`.`cars` (`owner_id`, `color`) VALUES (3, 'blue')      1   1   0
5   COMMIT      1   1   0

【讨论】:

  • 感谢您的努力!我再次检查了我的应用程序是否与我上面发布的代码不同,但它是相同的。任何想法,我还能在哪里寻找错误原因?
  • 是否启用了调试模式?配置::write('debug', 2);
  • 这也无济于事。 :( 还在找原因。会不会是我没有正确配置数据库架构?
  • 我不这么认为,我记得我有同样的问题。尝试清除 cakephp 中的缓存,只需在 config/core.php 中打开和关闭调试级别,然后尝试删除 /app/tmp/cache 文件夹中的所有文件。
  • 这就是我这两天正在做的事情——但没有任何结果。 :D 我什至用 CakePHP V 2.4.3 对其进行了测试,但没有任何帮助。无论如何,谢谢你的帮助!
【解决方案3】:

你能试试这个吗:

$this->Owner->saveAll($data);

代替

$this->Owner->saveAssociated($data, array('deep' => true));

谢谢

【讨论】:

  • 感谢您的想法,但这并没有做任何更改。
  • 是的,但这会产生与上述相同的查询。我正在尽一切努力让它发挥作用。
  • saveAll 和 saveAssociated 基本上是别名 - 你在这里没有什么不同的建议。
【解决方案4】:

不是一个实际的答案,但我刚刚测试了您的代码,它也适用于我。 (蛋糕2.4.5)

(default) 5 queries took 2 ms
Nr  Query   Error   Affected    Num. rows   Took (ms)
1   BEGIN       0   0   0
2   INSERT INTO `cake_test_2`.`owners` (`name`, `updated`, `created`) VALUES ('Me', '2014-02-24 00:57:11', '2014-02-24 00:57:11')       1   1   0
3   INSERT INTO `cake_test_2`.`cars` (`owner_id`, `color`) VALUES (1, 'red')        1   1   0
4   INSERT INTO `cake_test_2`.`cars` (`owner_id`, `color`) VALUES (1, 'blue')       1   1   1
5   COMMIT      1   1   1

如果您尝试仅使用这些必要的模型和控制器使用新的 CakePHP 实例,它仍然无法正常工作吗?

【讨论】:

  • 正如 Dezigos 答案的 cmets 中所述 - 我已经尝试过了。还有哪些其他框架条件可能导致它对我不起作用?
【解决方案5】:

注意:要让事务在 MySQL 中正常工作,您的表必须使用 InnoDB 引擎。请记住,MyISAM 表不支持事务。

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多