Core Data を使用して、次の対多関係でタグ付けシステムをセットアップしようとしています。
article.tags <<------->> tag.articles
このシナリオでは、article
は多数の を持つことができtags
、同じものtags
を複数の に割り当てることができますarticles
。のタグが編集されるたびに、以前に関連付けられていたものarticle
をすべて削除し、関連性のあるものを再度追加します。次のようにします。tags
article
// Remove any existing tags from this article
if(article.tags.count)
{
NSSet *existingEventTags = [article.tags copy];
for (NSManagedObject *tag in existingEventTags)
{
[[article mutableSetValueForKey:@"tags"] removeObject:tag];
[moc deleteObject:tag];
}
}
// Now re-assign any applicable tags to this article
for(NSString *tag in tags)
{
Tag *existingTag = [self existingTagWithString:tag];
if(existingTag)
{
[article addTagsObject:existingTag];
}
else
{
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Tag" inManagedObjectContext:moc];
Tag *newTag = (Tag *)[[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:moc];
newTag.name = tag;
[article addTagsObject:newTag];
}
}
私の質問は、2 つの関係に関連付けられた削除規則をどのように処理するのが最善かということです。基本的に私が探している動作は、tag
からを削除するときに、他にタグ付けされていarticle
ない場合にのみ完全に削除したいということです。articles
これを達成するために、tag.articles
関係を Nullify に設定し、articles.tags
関係を Cascade に設定しました。ただし、記事を削除すると、それに関連付けられているタグは (他の記事に関連付けられているかどうかに関係なく) 削除されます。これをテストするために、以下に含める簡単なデバッグ関数を作成しました。
- (void)debugTags
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Tag" inManagedObjectContext:moc];
[request setEntity:entity];
// Execute the fetch.
NSError *error = nil;
NSArray *objects = [moc executeFetchRequest:request error:&error];
if (objects != nil && [objects count] > 0)
{
NSLog(@"Found %d tags", [objects count]);
for(Tag *tag in objects)
{
NSLog(@"\t%@ (%d events)", tag.name, tag.articles.count);
}
}
else
{
NSLog(@"No tags found!");
}
}
完全を期すために、ここに出力例を示します ( articles
2 つの共有tags
: food と fastfood を使用した 2 つの作成を示します)。1 つを削除した後もarticle
、店内にはまだ食べ物やファストフードがあると思いますが、関係数は 1 です。
Before deletion
---------------
Found 4 tags
breakfast (1 events)
food (2 events)
fastfood (2 events)
lunch (1 events)
After deletion
--------------
Found 1 tags
lunch (1 events)