Базовые данные, эквивалентные рельсам: has_and_belongs_to_many =>,: through => - PullRequest
2 голосов
/ 11 июля 2010

У меня есть опыт работы с Rails, и я пытаюсь проникнуть через Core Data. Как Core Data обрабатывает сложные :has_and_belongs_to_many =>, :through => отношения?

В качестве примера, предположим, что вы моделировали вклады проекта с открытым исходным кодом. Вы можете настроить структуру таблицы, например:

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

В этом случае вы бы сказали, что и Contributor, и Project :has_and_belong_to_many друг от друга и что оба отношения :through являются таблицей присоединения Contribution Это позволяет хранить информацию об отношении внутри самого отношения (таблица взносов).

Удобные методы 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 ]

2 голосов
/ 12 июля 2010

В базовых данных вам нужно смоделировать отношения, «пересекающие» промежуточный объект самостоятельно, среда не сделает этого за вас. На самом деле в нем нет понятия «имеет много сквозного», такого как ActiveRecord в Rails, или «сплющенных отношений», как в Enterprise Objects Framework.

Тем не менее, вы можете легко реализовать свойства и методы для них. Например:

@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

Если вы хотите, чтобы ваши отношения "проектов" были модифицируемыми, они должны быть похожими. Обеспечение поддержки Key-Value Observing, скажем, если вам нужно привязать к нему, является более интересным - вам необходимо, чтобы ваш участник наблюдал за каждым из отношений своих проектов в Contributions и публиковал аналогичные уведомления KVO для своих собственных отношений «проектов» , Не так сложно, просто немного стандартного кода для написания.

0 голосов
/ 12 июля 2010

На самом деле, они в значительной степени одинаковы, потому что оба являются системами графов объектов.Словарный запас отличается.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, но из того, что я сделал, похоже,Базовые данные и Rails довольно близки по функциональности, это просто номенклатура, которая отличается.Базовые данные всегда имели графический редактор данных и предикаты, поэтому он использует меньше текстовых ярлыков, чем Rails.

0 голосов
/ 11 июля 2010

Посмотрите

// 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
...