Rails的核心数据等价物:has_and_belongs_to_many =>,:through =>

时间:2010-07-10 23:18:53

标签: ruby-on-rails core-data

我有一个Rails背景,我正试图破解核心数据。 Core Data如何处理复杂的:has_and_belongs_to_many =>, :through =>关系?

举个例子,假设您正在为开源项目贡献建模。您可以设置表结构,例如:

Contributor            Contribution             Project
----------------     ------------------     ------------------
name                   typeOfContribution       name
address                amountOfContribution     urlForSourceCode
...                    startedOnDate            ...
...                    endedOnDate              ...
                       contributor              
                       project  

在这种情况下,您会说贡献者和项目:has_and_belong_to_many彼此,并且两个关系都是:through贡献联接表。这使您可以存储关系本身内的关系信息(贡献表)。

Rails便捷方法也非常方便,因此您可以简单地浏览关系。例如:

contributor.projects   // this would return an array of project objects associated with the contributor
project.contributors   // this would return an array of contributors associated with a project

所以我的问题就是这样做的:

  1. 是否可以使用Core Data以类似的方式进行建模?和
  2. 如果是这样,关系是否可以像上面的代码一样轻松遍历(示例代码会很棒)?

3 个答案:

答案 0 :(得分:2)

在Core Data中,您需要自己建模“穿越”中间实体的关系,框架不会为您执行此操作。它实际上没有像Rails中的ActiveRecord那样的“有很多通过”的概念,或者像企业对象框架中那样的“扁平化关系”。

也就是说,您可以轻松地为它们实现属性和方法。例如:

@interface Contributor : NSManagedObject
@property (readonly, copy) NSSet *projects;
@end

@implementation Contributor
- (NSSet *)projects {
    // use aggregate KVC to do the iteration automatically
    return [self.contributions valueForKey:@"projects"]; 
}
@end

如果你需要改变你的“项目”关系,它应该是相似的。使它支持键值观察,比如你需要绑定它,更有趣 - 你基本上需要让你的贡献者观察它的每个贡献项目关系,并为自己的“项目”关系发布类似的KVO通知。不是那么难,只需要编写一些样板代码。

答案 1 :(得分:0)

实际上,它们都非常相同,因为它们都是对象图系统。词汇量不同。 Rails仍然保留了大部分关系数据库命名法,而Core Data使用了纯粹的面向对象的命名法。

而不是“表”核心数据具有表示运行时对象的属性和关系的“实体”。核心数据使用to-one( - >),to-many( - >>)命名关系每一端的关系。

因此,在您的示例中,您将拥有(伪代码):

Contributor{
    name:string;
    address:string;
    contributions<-->>Contribution.contributor;
}

Contribution{
    typeOfContribution:string;
    ...
    contributor<<-->Contributor.contributions;

}

Project{
    name:string;
    ...
    contributions<-->Contribution.project;
}

要查找以Contributor开头的项目,您可以使用谓词中的键路径来处理关系。类似的东西:

NSPredicate *aPred=[NSPredicate predicateWithFormat:@"project.name=%@",nameVariable];
NSSet *foundProjects=[aContributorObj.contributions filteredSetUsingPredicate:aPred];

这将获取与特定Contribution对象相关的所有Contributor对象,然后将键路径转到Contribution对象的项目关系,然后转到项目对象名称属性。如果name属性与nameVariable中的值匹配,则项目对象将返回到保留为foundProjects的集合。

我不是一个很大的Rails人,但从我所做的事情来看,Core Data和Rails在功能上相当接近,它只是命名法不同。 Core Data一直有图形数据建模器和谓词,所以它使用的文本快捷方式比Rails少。

答案 2 :(得分:-1)

看看

// this would return an array of project objects associated with the contributor
contributor.projects
// this would return an array of contributors associated with a project  
project.contributors


Class Contributor  < ActiveRecord::Base
   has_and_belongs_to_many :projects , :join_table => "contributions"
end

Class  Contribution  < ActiveRecord::Base 
end           

Class Project  < ActiveRecord::Base 
   has_and_belongs_to_many :contributors , :join_table => "contributions"
end
相关问题