2010-07-10 3 views
2

J'ai un arrière-plan Rails et j'essaie de passer à travers les données de base. Comment les données de base gèrent-elles les relations complexes :has_and_belongs_to_many =>, :through =>? Par exemple, supposons que vous étiez en train de modéliser des contributions de projet Open Source. Vous pouvez configurer une structure de table tels que:Equivalent de données de base de Rails: has_and_belongs_to_many =>,: through =>

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

Dans ce cas, vous dire que les deux Contributeur et le projet :has_and_belong_to_many les uns des autres, et que les deux relations sont :through la contribution se joindre à la table. Cela vous permet de stocker des informations sur la relation au sein de la relation elle-même (la table des cotisations).

Les méthodes pratiques de Rails sont également très pratiques, vous pouvez donc naviguer simplement dans les relations. Par exemple:

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 

Donc, ma question se résume à faire ceci:

  1. Est-il possible de modéliser d'une manière similaire à l'aide de base de données? et
  2. Si tel est le cas, les relations peuvent-elles être parcourues aussi facilement que le code ci-dessus (un exemple de code serait bon)?
+0

Salut: [email protected], j'ai besoin d'une sorte de configuration sur ma machine, j'ai intérêt à donner une réponse. Le lendemain je vais essayer d'obtenir une solution. – user386660

Répondre

2

Dans Core Data, vous devez modéliser vous-même les relations "traversant" l'entité intermédiaire, le framework ne le fera pas pour vous. Il n'a pas vraiment le concept de "a beaucoup à travers" comme ActiveRecord dans Rails ou "relations aplaties" comme dans l'Enterprise Objects Framework.

Cela dit, vous pouvez facilement implémenter des propriétés et des méthodes. Par exemple:

@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 

Si vous devez modifier la relation "projets", elle doit être similaire. Le rendre compatible avec Key-Value Observer, dire si vous avez besoin de vous lier, est plus intéressant - vous devez essentiellement faire en sorte que votre collaborateur observe toutes les relations de ses contributions et publie des notifications KVO similaires pour sa propre relation "projets" . Pas si difficile, juste un peu de code à écrire.

+0

Ok, cela a plus de sens pour moi. Donc je modéliserais la relation dans le .xcdatamodel, puis implémenterais les méthodes d'accesseur dans les modèles Contributor et Project. Cela me donnerait les méthodes "manquantes". Est-ce que je comprends bien le concept, mais pourriez-vous donner un peu plus de détails sur le KVO? Merci! –

+0

Vous comprenez bien. Désolé, je n'ai pas le temps d'entrer dans plus de détails sur ce que vous devez faire avec KVO. Je suggère de demander sur la liste de cacao-dev, ou de poser une question distincte sur Stack Overflow. –

-1

Jetez un oeil

// 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 
+0

La question était sur la façon de le faire dans Core Data dans Onjective-C, pas dans Ruby on Rails. –

0

En fait, ils sont tous les deux à peu près même parce que les deux sont des systèmes de graphe d'objet. Le vocabulaire est différent. Rails conserve une grande partie de la nomenclature des bases de données relationnelles alors que Core Data utilise une nomenclature purement orientée objet. À la place des «tables», les données de base ont des «entités» qui représentent les attributs et les relations des objets d'exécution. Les données de base désignent les relations à chaque extrémité de la relation en utilisant la fonction to-one (->), to-many (- >>).

Ainsi, dans votre exemple, vous auriez (pseudo-code):

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

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

} 

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

Pour trouver un projet à partir d'une Contributor, vous marcher sur la relation à l'aide d'un keypath dans un prédicat. Quelque chose comme:

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

Cela prendrait toutes les liées à l'objet spécifique Contributor puis marcher le keypath à la relation de projet de l'objet Contribution puis au projet d'objets attribut name objets Contribution. Si l'attribut name correspond à la valeur nameVariable, l'objet projet est renvoyé à l'ensemble détenu sous la forme foundProjects. Je ne suis pas un grand mec de Rails, mais d'après ce que j'ai pu voir, Core Data et Rails ont une fonctionnalité assez proche, c'est juste la nomenclature qui est différente. Les données de base ont toujours eu le modélisateur de données graphique et les prédicats, de sorte qu'il utilise moins de raccourcis textuels que Rails.

Questions connexes