Managing inverse relationships without CoreData - cocoa

This is a question for Objective-J/Cappuccino, but I added the cocoa tag since the frameworks are so similar.
One of the downsides of Cappuccino is that CoreData hasn't been ported over yet, so you have to make all your model objects manually.
In CoreData, your inverse relationships get managed automatically for you... if you add an object to a to-many relationship in another object, you can traverse the graph in both directions.
Without CoreData, is there any clean way to setup those inverse relationships automatically?
For a more concrete example, let's take the typical Department and Employees example. To use rails terminology, a Department object has-many Employees, and an Employee belongs-to a Department.
So our Department model has an NSMutableSet (or CPMutableSet ) "employees" that contains a set of Employees, and our Employee model has a variable "department" that points back to the Department model that owns it.
Is there an easy way to make it so that, when I add a new Employee model into the set, the inverse relationship (employee.department) automatically gets set? Or the reverse: If I set the department model of an employee, then it automatically gets added to that department's employee set?
Right know I'm making an object, "ValidatedModel" that all my models subclass, which adds a few methods that setup the inverse relationships, using KVO. But I'm afraid that I'm doing a lot of pointless work, and that there's already an easier way to do this.
Can someone put my concerns to rest?

I can't speak specifically to Objective-J, but the usual way of doing this without Core Data is to set the inverse relationship in the setter. So, using the employees/departments example, you would do something like this:
- (void)setDepartment:(Department *)aDepartment {
if (department == aDepartment)
return;
[department release];
department = [aDepartment retain];
[department addEmployee:self];
}
You need to make sure you don't update your instance variable if the new value already matches the existing value. If you didn't, setDepartment: would call addEmployee:, and addEmployee: would call setDepartment: in an infinite loop.
Also, note that this is an open invitation for retain cycles. It depends on how your model is structured, but the object that "owns" the the other is the one that should retain it. So my example is maybe not the best, because it's probably more accurate to say that the department "owns" the employee.

You probably want to set the relationship in your setter. Using your example the Objective-J code would look similar to this.
- (void)setDepartment:(Department)aDepartment {
if (department === aDepartment)
return;
[department addEmployee:self];
}
As you can see there is no need for retain / release. Objective-J is built upon javascript which is garbage collected. All the memory management methods are implemented but do nothing (apart from cluttering your code)
Also because this is javascript it's generally advisable to check for type equality (===) For more information on type equality see: http://www.webreference.com/js/column26/stricteq.html

check out the Cappuccino Extensions from this 280 North employee: http://github.com/nciagra/Cappuccino-Extensions
It includes an ActiveRecord port. I haven't actually looked at any of this up close yet, but it might help you.
Johannes

You can also check out this implementation of CoreData by rbartolome. I've only looked at it a little bit, but it looks like a start.
http://github.com/rbartolome/CoreData-Cappuccino

Related

Laravel / Eloquent special relation type based on parsed string attribute

I have developed a system where various classes have attributes consisting of a custom formula. The formula can contain special tokens which refer to different types of object. For example an object of class FruitSalad may have the following attribute;
$contents = "[A12] + [B76]";
In somewhat abstract terms, this means "add apple 12 to banana 76". It can also get significantly more complex than that with as many as 15 or 20 references to other objects involved in one formula.
I have a trait which passes formulae such as this and each time it finds a reference to a model (i.e. "[A12]") it gets it from the database with A::find(12) and adds it to an array of component objects which can be used for other processes later on in the request.
So, in essence, it's a relationship. But instead of a pivot table to describe the relationship, there is a formula on the parent model which can include references to child models.
This is all working. Yay! But it's really inefficient because there are so many tiny queries to get single models as formulae are parsed. One request may quite easily result in hundreds of queries. Oops.
I see two potential options;
1. Get all my apples and bananas from the database at the start of the request and get them from an in-memory store instead of from the database when parsing a formula (is this the repository pattern??).
2. Create a custom relation type (something like hasManyFromFormula) which makes eager loading work so that the parsing becomes much simpler because the relevant apples and bananas would already be loaded into the parent model.
Is there a precedent for this? As for why I am doing it like this, it would a bit tough to explain in brief but suffice to say it is to support a highly configurable data retrieval system which supports as-yet unknown input data configurations.
Help!
Thanks,
Geoff
Am not completely sure if it is the best solution, but in the end I created a new directory class for basic components and then set it up in the app service provider as a singleton. The constructor for the directory class loaded all models of several relevant classes and made them available as collections throughout the app.

'Existing Entity' constraint

I'm reading some data from an excel file, and hydrating it into an object of class A. Now I have to make sure that one of the fields of the data corresponds to the Id of a specific Entity. i.e:
class A{
protected $entityId;
}
I have to make sure that $entityId is an existing id of a specific entity (let's call it Foo). Now this can be achieved using the choice constraint, by supplying the choices option as all of the existing ids of Foo. However this will obviously cause a performance overhead. Is there a standard/better way to do this?
I'm a bit confused about what you are doing, since you seem to talk about Excel parsing, but at the same time you mention choices, which in my opinion relate to Forms.
IMO you should handle directly the relationship to your entity, instead of only its id. Most of the time it is always better to have directly the related entity as attribute of your class A than only the id, and Symfony manipulates such behaviours pretty well.
Then just have your Excel parser do something like this:
$relatedEntity = $this->relatedEntityRepository->find($entityId);
if (!$relatedEntity) {
throw new \Exception();
}
$entity->setRelatedEntity($relatedEntity);
After doing this, since you were talking about Forms, you can then use an EntityType field which will automatically perform the request in database. Use query_builder if you need to filter the results.

Should I save related models in repository?

I am working with Laravel for almost two years and trying to understand all the benefits of using Repositories and DDD. I still struggle with how to use best practices for working with data and models for better code reusability and nicer Architecture.
I have seen other developers suggesting to generate models in factories and then use Repositories for saving these models like :
public function add(User $user)
{
return $user->save();
}
but what should I do, in case my user model has models related with it, like images, description and settings.
Should I create repository for each model and call ->add() function 4 times in the controller or should I place the saving logic inside the UserRepository ->add() function passing all models as well as user? Also, how about update function, that logic might also be quite complicated.
Update - what I need is a practical example with realization.
It's always difficult to deal with "right way" questions. But here is one way.
From a DDD perspective, in this specific context, treat the User object as an aggregate root entity and the other objects as child value objects.
$description = new UserDescripton('Some description');
$image1 = new UserImage('head_shot','headshot.jpg');
$image2 = new UserImage('full_body','fullbody.jpg');
$user = new User('The Name',$description,[$image1,$image2]);
$userRepository->persist($user);
First thing to note is that you if really want to try and apply some of the ddd concepts then it is important to think in terms of domain models without worrying about how to persist them. If you find that you are basically writing a CRUD app with a bunch of getters and setters and almost no business logic then pretty much forget about it. All you will end up doing is to add complexity without much value.
The persist line is where the user will get stored. And you certainly don't want to have to write a bunch of code to store and update the children. Likewise, it would normally be waste of effort to make repositories for value objects. If you are going this route then you really need some sort of database layer that understands individual objects as well as their relations. It is the relations that are the key.
I assume you are using Laravel's Eloquent active record persistence layer. I'm not familiar enough with it to know how easy it is to persist and update an aggregate root.
The code I showed is actually based more on Doctrine 2 Object Relation Mapper and pretty much works out of the box. http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/ It is easy enough to integrate it with Laravel.
But even Doctrine 2 is largely CRUD oriented. In different domain contexts, the user object will be treated differently. It can start to get a bit involved to basically have different user implementations for different contexts. So make sure that the payoff in the domain layer is worth the effort.
I am not a PHP guy but from what I can find, Laravel an MVC framework, which has nothing to do with DDD.
Check this presentation, it does not to go to domain modelling, more concentrating on tactics but at least it has some goodness like command handling and domain events, briefly explains repositories with active record.
It also has references to two iconic DDD books at the last slide, I suggest you have a look at those too.

How do I represent multiple DTOs for a domain object in .NET Web API?

I'm writing a set of REST services and have come upon a problem that I'm sure has an appropriate solution/pattern that's just eluding me.
For instance /api/People/1 will return a serialized representation of PersonDto (which is a pared down representation of the Person domain object created by Entity Framework. I'm using AutoMapper to hydrate PersonDto.
However a second controller (say, /api/Classes/) is going to return different complex object, which may contain one or more Persons, however I want to represent each person in a different way than simply using an existing PersonDto (e.g. I might require more or less fields).
Do I need to define a ClassPersonDto? I'm not sure what the "proper" thing is to do here.
If the model of "person" being passed back in "Classes" is different then the "PersonDto" model, then yes, create a different model. You don't need to, but it's almost always better to keep your classes, including entities, as specific as possible.

Can a NSManagedObject own another as a property?

I've taught myself Obj-C, and have been self-teaching Cocoa, but adding Core Data to my program has given me nothing but a huge headache, thanks to me needing extensive custom logic. Here are a couple of the questions that are driving me insane.
What if I want a Managed Object to own another Managed Object? It seems if I give it a to-many relationship, the owned object will simply be shared by various masters, but I want each Owner to have its own.
If I subclass an NSManagedObject, can I make simple calls to the Array Controller to remove or copy instances of ManagedObject, and assume those will be translated into the Core Data model?
If I want to programmatically edit the properties of a ManagedObject, can I get away with mere KVC calls to the Array Controller? What's all this talk about NSPredicate an NSFetchRequest to the NSManagedObjectContext from the NSManagedDataStoreDrivingMeCrazy? Can I make an NSFetchRequest that filters the relationships of an object currently selected in a table view?
Once I use a fetch request to get a group of objects, how do I go about querying their relations? Does that require a whole other FetchRequest, Predicate, and so forth? Isn't Core Data supposed to be easier? Am I missing something?
An entity is similar to a class--it's a blueprint for a managed object that will be instantiated later. Each managed object will have its own attributes and relationships to configure.
You can definitely insert and delete managed objects. You might have to do some code to support copying, but I am not sure.
Yes, the properties (attributes and relationships) of managed objects support KVC (and KVO and bindings).
You can access the object or set of objects simply by using the relationship name that you define in the model (no additional fetch or logic is required).

Resources