由于关系,DataMapper 无法删除记录
Posted
技术标签:
【中文标题】由于关系,DataMapper 无法删除记录【英文标题】:DataMapper can't delete record because of relation 【发布时间】:2012-10-30 17:07:33 【问题描述】:我有这个带有 Torrent 和 Tag 的多对多 DataMapper/mysql 设置,如下所示:
class Torrent
include DataMapper::Resource
property :id, Serial
property :name, String
property :magnet, Text
property :created_at, DateTime
has n, :tags, :through => Resource
end
class Tag
include DataMapper::Resource
property :id, Serial
property :name, String
property :hits, Integer
has n, :torrents, :through => Resource
end
但是,当尝试通过Torrent.first.destroy
或类似的方式销毁种子时,DataMapper 会返回false
。
我尝试了像 delete from torrents where name like '%ubuntu%'
这样的直接 SQL 查询,但由于 MySQL 错误 1451 而失败:
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`brightswipe`.`tag_torrents`, CONSTRAINT `tag_torrents_torrent_fk` FOREIGN KEY (`torrent_id`) REFERENCES `torrents` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
我认为有一些 DataMapper 设置,在删除种子时我可以:
-
删除标签关联
删除种子
当删除标签时,我可以:
-
从所有带有该标签的种子中删除标签关联
删除标签
我该怎么办?
【问题讨论】:
【参考方案1】:尝试使用此插件自动管理关系:
https://github.com/datamapper/dm-constraints
这将允许您销毁 M:M 关联,尽管您必须手动清理关联表:
class Tag
...
has n, :torrents, :through => Resource, :constraint => :skip
class Torrent
...
has n, :tags, :through => Resource, :constraint => :skip
另一个选项是手动从 assocs 表中删除关系,然后您可以毫无问题地删除项目,因为您通过从 assocs 表中删除相应条目来破坏关系。
基本示例:
tr = Torrent.create
tg = Tag.create
tr.tags << tg
tr.save
tg.torrents << tr
tg.save
# destroying relation
TagTorrent.first(:tag => tg, :torrent => tr).destroy!
# or
tr.tag_torrents(:tag => tg).destroy
# or
tg.tag_torrents(:torrent => tr).destroy
# destroy items
tr.destroy!
tg.destroy!
【讨论】:
在删除种子时会删除标签关联吗?并在标签删除时删除标签关联? 另外,"constraint=>set_nil" 会引发 ArgumentError;对多对多关系无效。 然后请尝试:constraint => :skip
@silvu 请解释它的作用。
@silvu - 这将删除关系而不是删除另一个?我宁愿当标签被删除时,它们会从关联表中删除,反之亦然,当种子被删除时以上是关于由于关系,DataMapper 无法删除记录的主要内容,如果未能解决你的问题,请参考以下文章