【问题标题】:How do I add a HABTM record in CakePHP?如何在 CakePHP 中添加 HABTM 记录?
【发布时间】:2013-01-10 12:19:18
【问题描述】:

我是 CakePHP 新手,有一个相当基本的问题。 我有两张桌子:booksusersbooksusers 有一个习惯关系。我已经为上面创建了 MVC。 现在,当用户登录系统时,我希望用户能够通过查看“索引”操作的结果来预订一本书(即@9​​87654325@ 中的条目)。要使用的 API 是什么?

$this->Book->save() 似乎不合适,因为我们没有创建一本书。我们只需要现有的book 和登录的user 之间的关联。

我试图避免,检索 $this->Book,手动迭代子数组User,创建一个新的子数组并将整个内容保存回来。我相信一定有更简单的方法。

【问题讨论】:

  • 您是说您有两个表:booksusers,是吗?是否有您刚刚提到的第三个表 books_users 作为示例,但不是 real table,不是吗?如果你有第三张桌子,为什么不使用它的模型来将书籍保存给正确的用户
  • save() 如果您事先设置了 id,则不会创建新行。例如,您可以拥有$data['id'] = 3; $this->User->save($data);。这会将您的数据保存在 id = 3 的 User 中,系统将自动更新您的 books_users 表,其中 users = 3

标签: cakephp cakephp-2.2


【解决方案1】:

改编自 Chuck 的回答,不确定编辑被推迟的原因。


在 app/Model/Book.php 中

class Book extends AppModel {

    /************************************************************************
     * If you want your multiple assoc. to work you must set unique to      *
     * false, otherwise when you save an entry it will enforce unique       *
     * on book ID and subsequently your associations will delete previously *
     * saved associations, acting more like "User HasMany Books".           *
     ************************************************************************/

    var $hasAndBelongsToMany = array(
        'User' => array(
            'className' => 'User',
            'unique' => false                    
    ));

    public function addUser($bid, $uid) {
        $this->data['User']['id'] = $uid;
        $this->data['Book']['id'] = $bid;

        $this->save($this->data);
    }

}

在 app/Controller/BooksController.php(或 UsersController)中

$this->Book->addUser($bid, $uid);

胖模型/瘦控制器。允许重复条目(您需要限制限制并检查重复项,否则默认行为会使 HMBTM 变得困难)。完全按照您的意愿行事,您只需要提供图书和用户 ID。

CakePHP 不倾向于鼓励复杂的关联,这是因为 HMBTM 只是一种方便,在将其与其他关联混合时应小心,根据下面提供的链接,自定义关联比CakePHP 中的 HMBTM

http://book.cakephp.org/2.0/en/models/saving-your-data.html#what-to-do-when-habtm-becomes-complicated

【讨论】:

  • 编辑被拒绝,因为它完全改变了我的答案。虽然您的回答很好,但编辑旨在在不完全改变原始海报响应的情况下进行细微更改。使用编辑来修复拼写错误、调整语法或进行小修改。您的编辑完全重写。有意义吗?
  • 不用担心,只是想提供帮助,因为您的回答帮助了我。 :)
【解决方案2】:

您只需将包含两者 id 的记录保存到 Book 或 User,它就会将其插入到 HABTM 表中。

$this->data['User']['id'] = {USER_ID};
$this->data['Book']['id'] = {BOOK_ID};

$this->Book->save($this->data);

查看HABTM表,您会找到记录。

【讨论】:

  • 如果已经存在类似的行(相同的 USER_ID、BOOK_ID)会怎样?是否创建了重复行?
  • 取决于表中的约束。如果您将 USER_ID 和 BOOK_ID 设为唯一,则不,您将收到错误消息。如果不是,那么是的。您始终可以正确代码以首先检查记录,仅在未找到时才插入。这对beforeSave() 方法很有用。
【解决方案3】:

你烘焙你的应用程序了吗?我们将向您提供此(基本)功能供您调整。

简而言之-取书的id和用户的id。将其保存到您的 books_users 表中。

id | book_id | user_id
 1         1         1
 2         2         2
 3         2         3

如果您正确设置了关联,当您请求用户时,他们的所有书籍都将从连接表中返回。

您的逻辑将需要处理 - 可用书籍的数量,如果一个人可以一次预订多本书...

http://book.cakephp.org/2.0/en/models/saving-your-data.html#saving-related-model-data-habtm

举个例子。

【讨论】:

  • 我已经完成了烘焙并拥有 index/add/edit/del 操作和视图,这部分工作正常。但是,就我而言,我想知道用于从 BooksController 向用户添加一本书的 API。流程是 1) 用户查看索引视图,2) 选择一本书 3) 点击提交/添加,并将特定项目添加到 books_users 表中。
  • 您应该注意传递给Model::save() 的数组的结构。 HATBM 已被广泛讨论 - HereHereHere but with additional functionality。请注意,在第一个和第二个示例中,另一个模型在数组中有两个级别被传递给save()
  • 我在 habtmAdd 中收到以下错误“错误:SQLSTATE[42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册在第 1 行的 'habtmAdd' 附近使用的正确语法“我使用了 extend_associations.php 的原始版本和 2.x 版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
相关资源
最近更新 更多