CakePHP:创建新的 HABTM 行而不是更新其他行

2024-01-28

我有两个具有 HABTM(具有且属于多个)关系的模型:Qsets 和 Questions。

以下操作(在 QsetsController.php 中)应该会在 qsets_questions 表中产生一个新行,新问题出现在新的 qset 中。但相反它updates现有的行,导致该问题开始从先前的 qset 中获取并添加到新的 qset 中。

我究竟做错了什么?

public function admin_add_question( $qset_id, $question_id) {

    //find the qset...
    $qset = $this->Qset->find('first', array('id'=>$qset_id));

    $this->Qset->QsetsQuestion->create();
    $data = array(
            "Qset"=> array ("id"=>$qset_id),
            "Question"=>array ("id"=>$question_id)
    );
    Controller::loadModel('Question');
    $r= $this->Question->save($data);

    $this->Session->setFlash('Question id['.$question_id.'] added.');

    $this->redirect( $this->referer() );
}

如果我的描述不清楚,会发生以下情况:

在添加问题之前...

**Qset 1**
Question 1
Question 2

**Qset 2**
Question 3
Question 4

What should将问题 2 添加到 Qset 2 时发生

**Qset 1**
Question 1
Question 2

**Qset 2**
Question 3
Question 4
Question 2

相反会发生什么...

**Qset 1**
Question 1
          <----removed
**Qset 2**
Question 3
Question 4
Question 2

update: 这是我的 qsets_questions 表的转储:

CREATE TABLE `qsets_questions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `question_id` int(11) NOT NULL,
  `qset_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=64 ;

解决方案:

这是工作版本,感谢@nuns

public function admin_add_question( $qset_id, $question_id) {

    $this->Qset->QsetsQuestion->create();
    $data = array(
            "qset_id"=>$qset_id,
            "question_id"=>$question_id
    );
    Controller::loadModel('Question');
    $this->Question->QsetsQuestion->save($data);
    $this->Session->setFlash('Question id['.$question_id.'] added.');       
    $this->redirect( $this->referer() );
}

好的,这就是我的think正在发生:

你没有使用超级有用的 HABTM 关系魔法。 Cake 不将该表视为单纯的关系表,而是转到定义的模型并查看您定义的关系以及primaryKeys 和displayFields 等。

当您有一个复杂的 HABTM 表时,这没问题。但如果是这样的话,你的数据数组就乱了,因为你没有添加Question and Qset分别地。我的意思是,你没有做

$data = array('Question'=>array('title'=>'new_question'),
              'Qset'=>array('name'=>'lets say qset'));
$this->Question->saveAll($data);

这样做,你让 cake 为你解析 HABTM 关联,​​并且该数据结构就可以了。但是您的模型文件夹中有自己的 QsetsQuestion 模型。所以你保存的数据应该像任何其他表一样,就像这样

$data = array('qset_id'=> $qset_id,
              'question_id'=> $question_id);
$this->Question->QsetsQuestion->save($data);

这会在 qsets_questions 表中创建一个新的 id,并具有新的关系,就像您想要的那样。

不过要小心,因为你使用自己的模型,如果你没有正确设置验证,你可能会多次拥有同一对外键,因为默认情况下 cake 只是检查 id 必须是唯一的。

[EDIT]经过一番澄清后,上面的解决方案确实解决了“问题”,但实际上并不是这种行为的原因。

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

默认情况下,当保存 HasAndBelongsToMany 关系时,Cake 会 在保存新行之前删除连接表上的所有行。例如 如果您的俱乐部有 10 名相关儿童。然后你更新 俱乐部有 2 个孩子。俱乐部只有 2 名儿童,而不是 12 名。

因此,当您想要添加新行时,cake 会删除所有先前的关联并添加新的关联。解决这个问题的一个方法是找到所有Qsets属于一个问题并将它们添加到$data数组(添加您要添加​​的新问题关联)。这个链接 http://rottmann.net/2012/07/cakephp-hasandbelongstomany-relationship-queries-demystified/帮助我了解 HABTM 关联(查找“挑战 IV”)。

我知道我之前给出的解决方案可以帮助您解决“问题”,但它是在您有这样的印象的情况下做出的QsetsQuestion模型文件某处。既然你不这样做,解决方案就是获取所有Questions关联并将它们添加为新数组。Or实际上创建一个QsetsQuestion模型,并进行如下关联:

Qset hasMany QsetsQuestion
QsetsQuestion belongsTo Qset, Question
Question hasMany Qsets.

或者改变蛋糕的行为......我知道它们看起来都不漂亮。

因此,解决方案总结:

  • 每次要保存新的Qset-Question关联时,检索以前存储的关联,将其放入要保存的数组中,然后保存

    //find previously associated Qsets, lets say it's 1,2,3 and 4
    $data = array('Question'=>array('id'=>1),
              'Qsets'=>array('Qsets'=>array(1,2,3,4, $new_qset));
    $this->Question-save($data);
    

注意没有QsetsQuestion,因为它不存在。这应该是第一个选项,因为 HABTM 模型并不复杂

OR

  • Create QsetsQuestion在您的模型文件夹中并更改如上所述的关联。控制器上的保存部分是

    $data = array('qset_id'=>1, 'question_id'=>1)
    $this->Question->QsetsQuestion->save($data);    //also works with $this->Qset->QsetsQuestion
    

它要简单得多(也许),但是您必须创建一个新文件,并记住检查以前是否没有类似的关联(在插入之前检查 2-2 元组是否存在)。简单的验证规则应该有效。

OR

  • 为此改变 cakephp 行为...我不喜欢这个。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CakePHP:创建新的 HABTM 行而不是更新其他行 的相关文章

  • MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。添加了 11 条消息列表。使用emitter.setMaxListeners()来增加限制

    我知道这可能会标记为重复的解决方案 但堆栈溢出的解决方案对我不起作用 Problem node 5716 MaxListenersExceededWarning Possible EventEmitter memory leak detec
  • 删除行导致锁超时

    当我尝试从表中删除行时 我不断收到这些错误 这里的特殊情况是我可能同时运行5个进程 该表本身是一个 Innodb 表 约有 450 万行 我的 WHERE 子句中使用的列没有索引 其他指数按预期运行 这是在事务中完成的 首先删除记录 然后插
  • Woocommerce 让产品显示在存档页面中

    我正在尝试让所有产品显示在我商店的存档页面中 我想知道他们的id我正在使用我的一个钩子 它在 wp head 上运行并检查 if is product category 我想以某种方式访问 产品的查询并获取它们的 ID if is prod
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • MYSQL - 使用逗号分隔字符串作为变量输入的存储过程

    我希望有人能够提供帮助 我已经创建了我的第一个存储过程 没什么花哨的 但是我遇到了问题 我想给它一个字符串输入 例如 1 2 3 4 5 然后它执行一个简单的操作SELECT FROM TABLE WHERE EAN IN VAR 所以存储
  • 扩展蓝图类?

    我想覆盖timestamps 函数中发现Blueprint班级 我怎样才能做到这一点 e g public function up Schema create users function Blueprint table table gt
  • 将“php”作为 shell 脚本执行时的自定义 php.ini 文件

    我在跑php作为 shell 脚本 我不确定 shell脚本 是否正确 该文件以 usr bin php 这很好用 但 MongoDB 类没有正确加载php ini文件 具有extension mongo so 未使用 我该如何使用它tha
  • 使用 preg_replace 仅替换第一个匹配项

    我有一个结构类似于以下的字符串 aba aaa cba sbd dga gad aaa cbz 该字符串每次都可能有点不同 因为它来自外部源 我只想替换第一次出现的 aaa 但其他人则不然 是否可以 可选的第四个参数预替换 http php
  • 交换关联数组中的两个项目

    Example arr array apple gt sweet grapefruit gt bitter pear gt tasty banana gt yellow 我想调换一下柚子和梨的位置 这样数组就变成了 arr array ap
  • 使用 SSL 证书验证 Web 浏览器

    是否可以使用 ssl 证书对 Web 浏览器进行身份验证 假设我在应用程序中存储私钥 有什么方法可以从浏览器读取密钥并尝试基于该私钥进行身份验证 您可以使用 SSL TLS 客户端证书身份验证来对浏览器 用户进行身份验证 服务器必须请求客户
  • PHP 脚本可以在终端中运行,但不能在浏览器中运行

    我正在尝试执行exec命令 但我遇到了问题 当我运行以下代码时 当我通过浏览器运行它时它不起作用 但如果我把输出 str将其复制并粘贴到终端中 它工作得很好 造成这种情况的原因是什么 我该如何解决 目前我正在运行localhost php
  • Mysql插入表后不显示右单引号(’)

    我有一个名为 测试 的表 我插入了一行 其中包含unicode字符右单引号 0x2019在名称字段中 SQL insert into Testing values Sno Name Address insert into Testing v
  • 通过 $_SESSION 从一个脚本发送到另一个脚本期间数据丢失

    我正在尝试将一个充满属性的对象从一个 PHP 发送到另一个 PHP SESSION object obj where obj是一个用 foreach 循环指定的对象 foreach array of objects as obj SESSI
  • jQuery Mobile 表单验证

    我有一个移动网站 除了验证之外一切都工作正常 基本上我希望从用户那里获取值 然后在单独的页面 process php 上处理它们 但是 在这样做之前 我需要检查以确保字段已填充 我已经研究了几种方法来做到这一点 但似乎没有一种有效 我现在有
  • 在 apache docker 容器中运行虚拟主机

    我在同一个 apache 容器中有两个 php 应用程序 我试图在端口上运行其中一个应用程序 因为它需要通过根域而不是子文件夹进行访问 我想在端口 8060 上运行应用程序 我尝试使用 apache 虚拟主机执行此操作 但它不会加载页面 h
  • PHP HEREDoc (EOF) 语法在 Sublime Text 3 上突出显示与正斜杠的差异

    我不熟悉 Sublime Text 3 如何使用语法突出显示 例如 如果它纯粹依赖于主题 或者它内置于主题运行的标准中 但就我而言 使用 PHP 的 HERE 文档和转发存在一些语法突出显示差异斜线 一旦出现正斜杠 ST3 就会认为以下所有
  • CURL 中的 data-urlencode 是什么意思?

    我搜索了很多个小时试图弄清楚 php curl 中的 data urlencode 是什么 我尝试过这个 但我认为这是不对的 xmlpost object1 file https www lob com goblue pdf 在文档中是 d
  • php,统计字符并删除超过140个字符的内容

    我需要一个 PHP 函数来计算短语的字符数 如果短语长度超过 140 个字符 则此函数应删除所有其他字符并在短语末尾添加三个点 例如我们有 message I am what I am and you are what you are et
  • Magento - 自定义支付模块

    这是一个非常普遍的问题 但这里是 我正在尝试在 Magento 中创建一个自定义支付模块 我创建了一个 常规 模块 可以连接到 Magento 事件 观察者模型 但是我如何告诉 Magento 将模块视为支付模块 以便它显示在管理后端和结账
  • 对具有混合类型值的数组进行数字排序

    我有一个像这样的混合数组 fruits array lemon Lemon 20 banana apple 121 40 50 然后申请sort 其功能如下 sort fruits SORT NUMERIC foreach fruits a

随机推荐

  • Singleton httpclient 与创建新的 httpclient 请求

    我正在尝试使用 HttpClient 在我的网络服务中创建层Xamarin Forms移动应用 没有单例模式 具有单例模式 in first方法我在每个新请求中创建新的http客户端对象 通过移动应用程序 这是我的代码 public Htt
  • macOS 11 Big Sur 中具有自定义视图的 NSMenuItem

    macOS 11 Big Sur 当前版本 beta 1 到 beta 6 有一个错误 功能 使得 NSMenuItem 难以使用自定义视图 具体来说 当菜单项突出显示时 项目的自定义视图不会调用draw dirtyRect 我通过 NSM
  • 读取并绑定多个 csv 文件

    我有一系列 csv 文件 每个文件一个 具有相同的列标题和不同的行数 最初我是这样读入并合并它们的 setwd lt N Ring data by cruise Shetland LengthHeight2013 lt read csv N
  • jsp中的“页面范围”是什么?

    有以下范围JSP 页面范围 请求范围 会话范围 适用范围 我对页面范围感到困惑 谁能告诉我这是什么页面范围 我在任何地方都没有找到它的明确定义 page范围意味着 它可以被认为是代表整个JSP页面的对象 即JSP 对象只能从创建它的同一页面
  • 在 Eclipse 中添加库 v7 AppCompat 时如何解决错误“未找到与给定名称匹配的资源”?

    我的项目目标是 API 级别 10 我想实现新的 ActionBar 支持库 按照中的所有说明进行操作后支持库设置 http developer android com tools support library setup html 当将
  • file.choose() 在 Windows 上打开没有文件名的对话框

    当我使用file choose or choose files选择文件时 对话窗口会显示文件夹图标 但不显示文本 以前没有出现过这个问题 我不久前更新了 RStudio 但我不确定这是否是原因 我目前使用 R 4 1 1 和 RStudio
  • CertPathValidatorException:找不到证书路径的信任锚 - Retrofit Android

    我正在创建一个 Android 应用程序 它使用https用于与服务器通信 我在用retrofit and OkHttp用于提出请求 这些对于标准来说效果很好http要求 以下是我遵循的步骤 Step 1 使用命令从服务器获取证书文件 ec
  • 计算彩色图像的 HSV 直方图与 H-S 直方图有何不同?

    我想计算图像的 HSV 直方图 我搜索了很多 但没有发现任何有用的东西 在opencv在线指南中我找到了H S直方图 V 对光照有什么影响 HSV 和 H S 是否相同 意味着 V 对光照没有影响 这是H S直方图的代码 cvtColor
  • 将简单的 Antlr 语法转换为 Xtext

    我想将一个非常简单的Antlr语法转换为Xtext 所以没有句法谓词 https stackoverflow com questions 5728659 translate antlr grammar into xtext grammar
  • mathematica 如何确定在替换中首先使用哪个规则

    我想知道如果给定多个替换规则 mma 如何确定在发生碰撞时首先应用哪个规则 一个例子是 x 3 x 2 s x 3 s 2 s x x gt 0 x OddQ gt 2 Thanks Mathematica 有一种机制能够在简单情况下确定规
  • 从问题到 Wiki 的 GitHub 链接

    我想要链接维基页面来发布文本 语法链接到问题池中 text page 不起作用 怎么做 您还可以使用相对路径 这是我的一个项目的示例 Using a Shell Configuration File wikis Using a Shell
  • mySQL 分区多文件与单文件性能对比?

    对大型表进行分区时 我可以选择将标志 innodb file per table 设置为 TRUE 或 FALSE True 将创建许多文件 每个分区一个 并大大增加我的磁盘使用量 但允许我将分区分布在不同的卷上 我不打算这样做 FALSE
  • 区分手指触摸和手/掌托

    Is there any technique to differentiate between finger touch and palm rest on surface while drawing on touch surface in
  • F#:可以在运行时动态绑定度量单位吗?

    我对 F 非常陌生 对测量单位功能很感兴趣 并且大致了解它的正常工作原理 但想知道是否可以将测量值绑定到我们不知道测量值的值直到代码执行 我正在查看的实际示例是将浮点数绑定为货币值 其中度量单位是从数据库查找中推断出来的 假设每种货币 美元
  • 这个视图控制器是否在“willSet/didSet”对中泄漏?

    你有一个 vc 绿色 它有一个面板 黄色 支架 假设您有十个不同的视图控制器 价格 销售 库存 卡车 司机 调色板 您将一次将它们放入黄色区域 它将动态加载故事板中的每个 VC instantiateViewController withI
  • 开放 NLP 名称查找器培训

    我正在根据在线手册 http opennlp apache org documentation 1 5 2 incubating manual opennlp html 构建一个名为 en ner person train 的 15k 行训
  • MongoDB 中的“LIKE”命令(mongomapper)

    如何像 MongoDB 中的 sql 那样使用过滤数据 而不是在 Rails 应用程序上使用 gem mongomapper 谢谢 如果您要查找字符串的部分匹配项 可以使用正则表达式进行查询 这是 mongomapper 文档的相关部分 h
  • SharePoint 2010 - 从 Kerberos 更改为基于声明的身份验证

    我想在 SharePoint 2010 Enterprise Edition 环境中将身份验证提供程序从 Kerberos 更改为基于声明 我的 SharePoint 环境中可能会出现哪些问题 我听说如果 RSS 阅读器 Web 部件使用我
  • 需要算法帮助来查找 DAG 中的最大路径

    假设我有这个有向无环图 DAG http en wikipedia org wiki Directed acyclic graph 其中从每个节点 底行中的节点除外 到其下面的两个节点都有一条有向边 7 3 8 8 1 0 2 7 4 4
  • CakePHP:创建新的 HABTM 行而不是更新其他行

    我有两个具有 HABTM 具有且属于多个 关系的模型 Qsets 和 Questions 以下操作 在 QsetsController php 中 应该会在 qsets questions 表中产生一个新行 新问题出现在新的 qset 中