我有3个表,例如数据库中的一个article表,一个tag表,一个article_tag表。 文章和标签是N-M关系。
当我需要添加新文章时,使用 Yii2 的事件记录的 link() 方法将关系保存到联结表,它工作正常。
但是当我需要更新联结表时。如果我再次调用文章的 link() 方法。不起作用。下面是我的代码和错误信息。
$tag_ids = Yii::$app->request->post('Article')['tags'];
foreach ($tag_ids as $value) {
$tag = Tag::findOne($value);
$model->link('tags', $tag);
}
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '13-1' for key 'PRIMARY'
The SQL being executed was: INSERT INTO `article_tag` (`article_id`, `tag_id`) VALUES (13, 1)
我是否需要删除联结表中的所有数据然后使用 link() 更新它??还是 Yii2 缺少某些功能?
------------------------更新-------------------- ------------------
看来我需要自己用纯sql来做。我想到的最简单的方法是先删除联结表中的数据,然后再次使用 link() 填充数据透视表。这很简单,但会弄乱索引。 table 也增长得很快。第二种方法是读取每条记录,然后决定保留或删除它。然后添加必要的数据。这种方法使它更复杂。需要更多代码。
----------------再次更新我写了一个函数------------------------
public function syncTags($new_tag_ids){
$old_tag_ids = ArrayHelper::getColumn($this->tags, 'id');
$tag_to_delete = array_diff($old_tag_ids, $new_tag_ids);
$tag_to_add = array_diff($new_tag_ids, $old_tag_ids);
if($tag_to_delete){
//delete tags
Yii::$app->db->createCommand()
->delete('article_tag', ['article_id' => $this->id, 'tag_id' => $tag_to_delete])
->execute();
}
if($tag_to_add){
//link new tag assisoated with the article
foreach ($tag_to_add as $value) {
$tag = Tag::findOne($value);
$this->link('tags', $tag);
}
}
}
它现在正在唤醒,但不是全局适用的。我认为它可能对人们有所帮助 所以在这里发帖。 Yii 需要为这些工作扩展..
最佳答案
大多数时候我只用这个方法。第二种解决方案也有效,但我更喜欢第一种。我是那种喜欢在没有他人帮助的情况下解决问题的人。
/**
* Update categories with the new ones
* @param array $categories [description]
* @return null
*/
public function updateCategories($categories = [])
{
$this->unlinkAll('categories', true);
if ( ! is_array($categories))
return ;
foreach ($categories as $category_id)
{
$category = Category::findOne($category_id);
$this->link('categories', $category);
}
// alternative solution
/*
$old_categories = $this->getCategories()->asArray()->column(); // get all categories IDs
if ( ! is_array($categories))
$categories = [];
$inserted_categories = array_diff($categories, $old_categories);
$deleted_categories = array_diff($old_categories, $categories);
foreach ($inserted_categories as $category_id)
{
$category = Category::findOne($category_id);
$this->link('categories', $category);
}
foreach ($deleted_categories as $category_id)
{
$category = Category::findOne($category_id);
$this->unlink('categories', $category, true);
}
*/
}
关于php - Yii2 更新与 Active Record 多对多关系的联结表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33753923/
这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby类,但是我如何得到ActiveRecord关联这个类模型
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。
根据ActiveRecord::Base的文档:==(comparison_object)Returnstrueifcomparison_objectisthesameexactobject,orcomparison_objectisofthesametypeandselfhasanIDanditisequaltocomparison_object.id.Notethatnewrecordsaredifferentfromanyotherrecordbydefinition,unlesstheotherrecordisthereceiveritself.Besides,ifyoufet
我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下
我在非Rails项目中使用ActiveRecord。在Rails中,我可以这样做:config.time_zone='EasternTime(US&Canada)'config.active_record.default_timezone='EasternTime(US&Canada)'但如果我不使用rails,我该如何设置时区? 最佳答案 ActiveRecord::Base.default_timezone='EasternTime(US&Canada)' 关于ruby-没有轨道的A
📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年
我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U