Skip to content
This repository

Externally exposing the lookupKey/relatedByAttribute #396

Closed
wants to merge 10 commits into from

2 participants

StuFF mc Tony Arnold
StuFF mc

Allows to use it like [[MyEntity entityDescription] lookupKey] — Maybe we could call this relatedByAttribute and move it to CoreData+MagicalRecord.h as a class method.

stuffmc added some commits
StuFF mc stuffmc Externally exposing the lookupKey to use it like `[[MyEntity entityDe…
…scription] lookupKey]` (Maybe we could call this `relatedByAttribute` and move it to `CoreData+MagicalRecord.h` as a class method.
1eda669
StuFF mc stuffmc Removed comments in MR_importFromArray + more close to coding style o…
…f the project.
5cad1dd
StuFF mc stuffmc Passing a ManagedObject to MR_importFromObject: allows to "duplicate"…
… that Object like with a NSDictionary. Skipping relationships in this case.
230b244
Tony Arnold
Owner

Looks good to me — thanks for fixing up the stylistic things, @stuffmc! We should remember to add MR_lookupKey to the shorthand header, too.

StuFF mc

Oh, wow. So this is the way Pull Requests works? Everytime I'll add something in my branch stuffmc you guys will get noticed? That's "interesting" — Now that I know that Maybe I should push to "my" experimental and when there are things I don't want to be merged here (or in dev for example).

Tony Arnold
Owner

Generally, the best approach is to create "feature branches". Basically, make discrete changes, create a new branch for each of them. Related changes are OK, but getting a whole swag of unrelated code to review is no fun.

Have a read of A successful Git branching model — this is how we have been working for the last couple of months with MR, and it's how we'd prefer to receive changes and pull requests.

That all said, any method of contribution is welcome and if there's merit in what you've done (even if it's a mega messy pull request) we might still cherry pick out the individual changes we want to merge.

Tony Arnold
Owner

Given the age of this issue, and the volume of issues we have to work through, I've decided to close this alongside a number of other older issues.

If you can still replicate the issue under the latest in-development version of MagicalRecord (3.0 at the time of writing), please feel free to re-open and one of @magicalpanda/team-magicalrecord will take another look. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 10 unique commits by 1 author.

Jan 24, 2013
StuFF mc stuffmc Externally exposing the lookupKey to use it like `[[MyEntity entityDe…
…scription] lookupKey]` (Maybe we could call this `relatedByAttribute` and move it to `CoreData+MagicalRecord.h` as a class method.
1eda669
StuFF mc stuffmc Removed comments in MR_importFromArray + more close to coding style o…
…f the project.
5cad1dd
Jan 26, 2013
StuFF mc stuffmc Passing a ManagedObject to MR_importFromObject: allows to "duplicate"…
… that Object like with a NSDictionary. Skipping relationships in this case.
230b244
StuFF mc stuffmc NSString Addition "MR_sortKeys" (and the corresponding define) allows…
… to use it in other contexts.
389fe44
StuFF mc stuffmc Shorthand method for getting the numberOfRows of a NSFetchedResultCon…
…troller section without having to do the NSFetchedResultsSectionInfo Samba.
b2706b6
StuFF mc stuffmc Is this the way we should create ShortHands? Unsure — Where would tha…
…t be documented?
2f34253
Jan 28, 2013
StuFF mc stuffmc Fixing a double @interface block 1bd927b
StuFF mc stuffmc Throwing an exception when the developer forgot to pass a non nil att…
…ribute to the method.
23886ed
StuFF mc stuffmc When an entity has a super entity, if no 'primaryAttribute' is found,…
… going upwards the hierarchy looking for one.
76af2ae
Jan 29, 2013
StuFF mc stuffmc MR_lookupkey will now look in the superentity if the "supposed" prima…
…ry key doesn't exist.
d2ed7c2
This page is out of date. Refresh to see the latest.
1  MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.h
@@ -11,5 +11,6 @@
11 11
12 12 - (NSAttributeDescription *) MR_primaryAttributeToRelateBy;
13 13 - (NSManagedObject *) MR_createInstanceInContext:(NSManagedObjectContext *)context;
  14 +- (NSString*) MR_lookupKey;
14 15
15 16 @end
25 MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m
@@ -12,12 +12,15 @@ @implementation NSEntityDescription (MagicalRecord_DataImport)
12 12
13 13 - (NSAttributeDescription *) MR_primaryAttributeToRelateBy;
14 14 {
15   - NSString *lookupKey = [[self userInfo] valueForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: primaryKeyNameFromString([self name]);
16   - NSDictionary *attributesByName = [self attributesByName];
17   -
18   - if ([attributesByName count] == 0) return nil;
19   -
20   - NSAttributeDescription *primaryAttribute = [attributesByName objectForKey:lookupKey];
  15 + NSEntityDescription *entityDescription = self;
  16 + NSAttributeDescription *primaryAttribute = nil;
  17 + do {
  18 + NSDictionary *attributesByName = [entityDescription attributesByName];
  19 + if ([attributesByName count]) {
  20 + primaryAttribute = [attributesByName objectForKey:[entityDescription MR_lookupKey]];
  21 + };
  22 + entityDescription = entityDescription.superentity;
  23 + } while (!primaryAttribute && entityDescription);
21 24
22 25 return primaryAttribute;
23 26 }
@@ -30,5 +33,15 @@ - (NSManagedObject *) MR_createInstanceInContext:(NSManagedObjectContext *)conte
30 33 return newInstance;
31 34 }
32 35
  36 +- (NSString*) MR_lookupKey
  37 +{
  38 + NSString *primaryKeyName = [[self userInfo] valueForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: primaryKeyNameFromString([self name]);
  39 + if ([[[self attributesByName] allKeys] containsObject:primaryKeyName]) {
  40 + return primaryKeyName;
  41 + } else {
  42 + NSString *primaryKeyNameInSuperentity = [[self superentity] MR_lookupKey];
  43 + return primaryKeyNameInSuperentity ?: primaryKeyName;
  44 + }
  45 +}
33 46
34 47 @end
20 MagicalRecord/Categories/NSFetchedResultsController+MagicalRecord.h
... ... @@ -0,0 +1,20 @@
  1 +//
  2 +// NSFetchedResultsController+MagicalRecord.h
  3 +// wetter-com-iphone
  4 +//
  5 +// Created by Manuel "StuFF mc" Carrasco Molina on 26.01.13.
  6 +// Copyright (c) 2013 grandcentrix GmbH. All rights reserved.
  7 +//
  8 +
  9 +#import <CoreData/CoreData.h>
  10 +
  11 +#if TARGET_OS_IPHONE
  12 +
  13 +@interface NSFetchedResultsController (MagicalRecord)
  14 +
  15 +- (NSInteger)MR_numberOfObjectsInSection:(NSUInteger)section;
  16 +- (NSUInteger)MR_fuzzyNumberOfObjectsInSection:(NSUInteger)section;
  17 +
  18 +@end
  19 +
  20 +#endif
34 MagicalRecord/Categories/NSFetchedResultsController+MagicalRecord.m
... ... @@ -0,0 +1,34 @@
  1 +//
  2 +// NSFetchedResultsController+MagicalRecord.m
  3 +// wetter-com-iphone
  4 +//
  5 +// Created by Manuel "StuFF mc" Carrasco Molina on 26.01.13.
  6 +// Copyright (c) 2013 grandcentrix GmbH. All rights reserved.
  7 +//
  8 +
  9 +#import "NSFetchedResultsController+MagicalRecord.h"
  10 +
  11 +#if TARGET_OS_IPHONE
  12 +
  13 +@implementation NSFetchedResultsController (MagicalRecord)
  14 +
  15 +- (NSInteger)MR_numberOfObjectsInSection:(NSUInteger)section
  16 +{
  17 + NSUInteger count = -1; // This means section out of index in a nicer way!
  18 + if (section < self.sections.count) {
  19 + id<NSFetchedResultsSectionInfo> info = self.sections[section];
  20 + count = [info numberOfObjects];
  21 + }
  22 + return count;
  23 +}
  24 +
  25 +- (NSUInteger)MR_fuzzyNumberOfObjectsInSection:(NSUInteger)section
  26 +{
  27 + NSInteger count = [self MR_numberOfObjectsInSection:section];
  28 + count = (count > 0) ? count : 0;
  29 + return count;
  30 +}
  31 +
  32 +@end
  33 +
  34 +#endif
31 MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m
@@ -44,7 +44,7 @@ - (void) MR_setAttributes:(NSDictionary *)attributes forKeysWithObject:(id)objec
44 44 for (NSString *attributeName in attributes)
45 45 {
46 46 NSAttributeDescription *attributeInfo = [attributes valueForKey:attributeName];
47   - NSString *lookupKeyPath = [objectData MR_lookupKeyForAttribute:attributeInfo];
  47 + NSString *lookupKeyPath = [objectData isKindOfClass:[self class]] ? attributeName : [objectData MR_lookupKeyForAttribute:attributeInfo];
48 48
49 49 if (lookupKeyPath)
50 50 {
@@ -205,8 +205,10 @@ - (BOOL) MR_performDataImportFromObject:(id)objectData relationshipBlock:(void(^
205 205 NSDictionary *attributes = [[self entity] attributesByName];
206 206 [self MR_setAttributes:attributes forKeysWithObject:objectData];
207 207
208   - NSDictionary *relationships = [[self entity] relationshipsByName];
209   - [self MR_setRelationships:relationships forKeysWithObject:objectData withBlock:relationshipBlock];
  208 + if (![objectData isKindOfClass:[self class]]) { // Not importing Relationships when the object is a ManagedObject — I was otherwise in an infinite loop.
  209 + NSDictionary *relationships = [[self entity] relationshipsByName];
  210 + [self MR_setRelationships:relationships forKeysWithObject:objectData withBlock:relationshipBlock];
  211 + }
210 212
211 213 return [self MR_postImport:objectData];
212 214 }
@@ -234,7 +236,7 @@ + (id) MR_importFromObject:(id)objectData inContext:(NSManagedObjectContext *)co
234 236 {
235 237 NSAttributeDescription *primaryAttribute = [[self MR_entityDescription] MR_primaryAttributeToRelateBy];
236 238
237   - id value = [objectData MR_valueForAttribute:primaryAttribute];
  239 + id value = [objectData isKindOfClass:self] ? [objectData valueForKey:[[self MR_entityDescription] MR_lookupKey]] : [objectData MR_valueForAttribute:primaryAttribute];
238 240
239 241 NSManagedObject *managedObject = [self MR_findFirstByAttribute:[primaryAttribute name] withValue:value inContext:context];
240 242 if (managedObject == nil)
@@ -259,28 +261,7 @@ + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData
259 261
260 262 + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData inContext:(NSManagedObjectContext *)context
261 263 {
262   -// NSMutableArray *objectIDs = [NSMutableArray array];
263   -//
264   -// [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
265   -// {
266   -// [listOfObjectData enumerateObjectsWithOptions:0 usingBlock:^(id obj, NSUInteger idx, BOOL *stop)
267   -// {
268   -// NSDictionary *objectData = (NSDictionary *)obj;
269   -//
270   -// NSManagedObject *dataObject = [self MR_importFromObject:objectData inContext:localContext];
271   -//
272   -// if ([context obtainPermanentIDsForObjects:[NSArray arrayWithObject:dataObject] error:nil])
273   -// {
274   -// [objectIDs addObject:[dataObject objectID]];
275   -// }
276   -// }];
277   -// }];
278   -//
279   -// return [self MR_findAllWithPredicate:[NSPredicate predicateWithFormat:@"self IN %@", objectIDs] inContext:context];
280   -
281   -
282 264 // See https://gist.github.com/4501089 and https://alpha.app.net/tonymillion/post/2397422
283   -
284 265 NSMutableArray *objects = [NSMutableArray array];
285 266
286 267 [listOfObjectData enumerateObjectsWithOptions:0
3  MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.m
@@ -102,7 +102,8 @@ + (id) MR_findFirst
102 102 }
103 103
104 104 + (id) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context
105   -{
  105 +{
  106 + NSAssert(attribute != nil, @"attribute can't be nil — You either need to use 'relatedByAttribute' or use 'entityID'...");
106 107 NSFetchRequest *request = [self MR_requestFirstByAttribute:attribute withValue:searchValue inContext:context];
107 108 // [request setPropertiesToFetch:[NSArray arrayWithObject:attribute]];
108 109
2  MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.m
@@ -115,7 +115,7 @@ + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)
115 115 [request setFetchBatchSize:[self MR_defaultBatchSize]];
116 116
117 117 NSMutableArray* sortDescriptors = [[NSMutableArray alloc] init];
118   - NSArray* sortKeys = [sortTerm componentsSeparatedByString:@","];
  118 + NSArray* sortKeys = [sortTerm MR_sortKeys];
119 119 for (NSString* sortKey in sortKeys)
120 120 {
121 121 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:ascending];
16 MagicalRecord/Categories/NSString+MagicalRecord.h
... ... @@ -0,0 +1,16 @@
  1 +//
  2 +// NSString+MagicalRecord.h
  3 +// wetter-com-iphone
  4 +//
  5 +// Created by Manuel "StuFF mc" Carrasco Molina on 26.01.13.
  6 +// Copyright (c) 2013 grandcentrix GmbH. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +
  11 +@interface NSString (MagicalRecord)
  12 +
  13 +#define MR_SORT_KEY_SEPARATOR @","
  14 +@property (strong, nonatomic, readonly) NSArray *MR_sortKeys;
  15 +
  16 +@end
18 MagicalRecord/Categories/NSString+MagicalRecord.m
... ... @@ -0,0 +1,18 @@
  1 +//
  2 +// NSString+MagicalRecord.m
  3 +// wetter-com-iphone
  4 +//
  5 +// Created by Manuel "StuFF mc" Carrasco Molina on 26.01.13.
  6 +// Copyright (c) 2013 grandcentrix GmbH. All rights reserved.
  7 +//
  8 +
  9 +#import "NSString+MagicalRecord.h"
  10 +
  11 +@implementation NSString (MagicalRecord)
  12 +
  13 +- (NSArray*)MR_sortKeys
  14 +{
  15 + return [self componentsSeparatedByString:MR_SORT_KEY_SEPARATOR];
  16 +}
  17 +
  18 +@end
16 MagicalRecord/Core/MagicalRecordShorthand.h
... ... @@ -1,11 +1,5 @@
1 1 #ifdef MR_SHORTHAND
2 2
3   -
4   -
5   -
6   -
7   -
8   -
9 3 @interface NSManagedObject (MagicalAggregationShortHand)
10 4 + (NSNumber *) numberOfEntities;
11 5 + (NSNumber *) numberOfEntitiesWithContext:(NSManagedObjectContext *)context;
@@ -184,11 +178,11 @@
184 178 - (void) addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent;
185 179 - (void) addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock;
186 180 @end
187   -
188   -
189   -
190   -
191   -
  181 +@interface NSEntityDescription (MagicalRecordShortHand)
  182 +- (NSAttributeDescription *) primaryAttributeToRelateBy;
  183 +- (NSManagedObject *) createInstanceInContext:(NSManagedObjectContext *)context;
  184 +- (NSInteger)numberOfObjectsInSection:(NSUInteger)section;
  185 +@end
192 186
193 187 #endif
194 188
3  MagicalRecord/CoreData+MagicalRecord.h
@@ -40,10 +40,13 @@
40 40 #import "NSNumber+MagicalDataImport.h"
41 41 #import "NSObject+MagicalDataImport.h"
42 42 #import "NSString+MagicalDataImport.h"
  43 + #import "NSString+MagicalRecord.h"
43 44 #import "NSAttributeDescription+MagicalDataImport.h"
44 45 #import "NSRelationshipDescription+MagicalDataImport.h"
45 46 #import "NSEntityDescription+MagicalDataImport.h"
46 47
  48 + #import "NSFetchedResultsController+MagicalRecord.h"
  49 +
47 50 #endif
48 51
49 52 // @see https://github.com/ccgus/fmdb/commit/aef763eeb64e6fa654e7d121f1df4c16a98d9f4f

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.