【问题标题】:DataMapper can't delete record because of relation由于关系,DataMapper 无法删除记录
【发布时间】: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. 删除标签关联
  2. 删除种子

当删除标签时,我可以:

  1. 从所有带有该标签的种子中删除标签关联
  2. 删除标签

我该怎么办?

【问题讨论】:

    标签: mysql ruby orm relational-database 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 =&gt; :skip
    • @silvu 请解释它的作用。
    • @silvu - 这将删除关系而不是删除另一个?我宁愿当标签被删除时,它们会从关联表中删除,反之亦然,当种子被删除时
    猜你喜欢
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-29
    相关资源
    最近更新 更多