DataMapper can't delete record because of relation

微笑、不失礼 提交于 2019-12-24 01:04:52

问题


I have this many-many DataMapper/MySQL setup with Torrent and Tag, as follows:

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

When trying to destroy a torrent, however, via Torrent.first.destroy or something similar, DataMapper returns false.

I tried straight SQL queries like delete from torrents where name like '%ubuntu%', which failed because of MySQL error 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)

I figure there's some DataMapper setup whereby when deleting a torrent I can:

  1. Remove the tag associations
  2. Delete the torrent

And when deleting a tag I can:

  1. Remove the tag association from all torrents with that tag
  2. Delete the tag

How can I go about this?


回答1:


try using this plugin to have relations managed automatically:

https://github.com/datamapper/dm-constraints

This will allow you to destroy M:M assocs though you'll have to cleanup the assocs table manually:

class Tag
  ...
  has n, :torrents, :through => Resource, :constraint => :skip

class Torrent
  ...
  has n, :tags, :through => Resource, :constraint => :skip

Another option is to remove the relation from assocs table manually, then you'll can remove items without any issues, cause you destroyed the relation by removing corresponding entry from assocs table.

basic example:

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!


来源:https://stackoverflow.com/questions/13144198/datamapper-cant-delete-record-because-of-relation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!