Creating a Core Data Inverse Relationship - cocoa

I'm trying to write my first Cocoa app, and Core Data is making it difficult to model my data objects. I have two entities that I want to manipulate: Account and Transaction. Account has a human-readable name and that's about it. Transaction stores a monetary value, and references to two accounts called debitAccount and creditAccount (I'm working on a double-book accounting app).
I want to be able to find all the Transactions for a given Account, whether they use debitAccount or creditAccount. How can I do this? Is there a way to do it that will work easily with Cocoa UI binding?

If I understand you correctly, you want Transaction to be related to Account via two relationships: debitAccount and creditAccount, yes? And you're wondering about creating inverse relationships.
In short, a relationship can only be the inverse of one other relationship. So you won't be able to create a relationship called, say, transactions that is the inverse of both debitAccount and creditAccount. Instead, you'll have to create two relationships, like debitTransactions and creditTransactions (I'm sure you'll think of more appropriate names for these...)
Now, since relationships are modeled as sets (specifically, NSSets), you can union the creditTransactions and debitTransactions relationships for a particular Account to get all transactions that account is involved with.
A (possibly better) alternative would be to introduce an intermediate entity, with a name like TransactionAccount that has a to-one relationship to both Account and Transaction as well as an attribute, like accountRole that identifies the account as being the debit or credit account relative to that particular transaction. You'd create inverse to-many relationships on both Transaction and Account with a name like transactionAccounts. That way, you could write something like this:
[account valueForKeyPath:#"transactionAccounts.transaction"]
to get all the transactions for a particular account. You could use an NSPredicate to filter the set to only transactions where the account was the debit/credit account.

The solution that worked best (and made the most sense) to me was to create a subclass of NSManagedObject to use as my Account entity:
#interface Account : NSManagedObject {
}
-(NSArray*)getTransactions;
#end
I have the actual lookup logic inside -getTransactions, which wasn't too hard to do by hand. This is working out well so far, especially because the method name conforms to KVO.
To make Core Data return Accounts instead of NSManagedObjects, I had to change the entity's "Class" property in Xcode's data modeling tool.

Related

How to have a User Account for different entities in Spring JPA?

I'm making a system (using Spring + JPA with MySQL) that shows the best applicants for a certain job offer. The company and the applicants have their respective user account, and with that, they can fill in their personal/company information and their job profile/job offer conditions. With that, the system should match the job conditions (like 3+ years of experience in C) with the applicant's job profile.
My problem is that the User Account is created first, and should be independent, but these two different entities (Applicant and Company), with different attributes, are using it. So if I do something like create an applicant and company in the User Account, one of them will be always null.
How can I solve this? I guess the problem would be something like: how to implement a user account that can hold data from different entities that have different attributes (therefore, can't be grouped)? (In fact, I need one more entity, but I tried to simplify it to illustrate the problem more clearly).
I think, you should make marker interface, like public interface UserAccountable or smth. Implement this interface in your Applicant and Company classes. Then you can make a field in UserAccount class, like private UserAccountable someUser; and throught setters and getters you can assign and get this variable to Applicant or Company.
Hope this helps!
I found what I needed here: https://thoughts-on-java.org/complete-guide-inheritance-strategies-jpa-hibernate/
The problem was the mapping, not the class design per se. I could create interfaces and abstract classes to solve it in the Java world, but in the SQL world that's not possible, so the mapping is the key. In this case, I was looking for the Joined table mapping, but I realized I needed it just to not have null fields in my UserAccount, because I don't need a polymorphic query (e.g. give me the names of every 'user type' (Person, Company)), and it would be too costly performance wise to implement it that way, so I'll trade off space for performance, and I'll just reference all three user types in the User Account, leaving two of those three fields null forever.
PS: Single table mapping won't help because I do need to use not null conditions.

How to store log of all changes to Eloquent model in Laravel 5.4?

I want to store changes to all fields in Eloquent model into database.
I can do it using created and updated events but there is a problem with multiple foreign relations (described as separate tables).
Example:
User
login
Roles -> hasMany
When I update login field it is easy to write old and new value into database, but when I update Roles relation nothing happens.
How can I track all foreign relations (like hasMany, hasManyThrough, ManyToMany)?
Owen-it has a very nice Library called laravel-auditing, which keeps an easy to query list of all changes that are made to a model, and I think it does quite an awesome piece of work. Have used it and it is worth it to try out.
There is no embedded and simple method to do it.
Eloquent doesn't provide any method to implement observers on related models by design. Many proposal in this way have been rejected by Taylor (just one example).
The only thing you can do, is to create your own methods to do it.
You have many possibilities, here are some of them in order of complexity (some of them are "dirty" :-)
add a created and updated observer on each related model
override the save() or create your own saveAndFire() method on your eloquent instances, and from that method retrieve the parent and call its log methods before saving. (this is a little bit "dirty" imho)
encapsulate all your persistence layer and fire events yourself on saving objects (look at the repository pattern, for example)

Which objects are responsible for maintaining references between aggregates?

Suppose I have one aggregate, Ticket. A Ticket will have one assigned Department and one or more assigned Employee.
When instantiating a Ticket, should a TicketFactory be responsible for ensuring that a Ticket is created with a valid/existent Department and Employee?
Likewise, when decommissioning a Department or Employee, what is responsible for ensuring that a new Department or Employee is assigned to a Ticket so as to maintain its invariants? Could there be a service in the domain responsible for decommissioning, or is this a case where eventual consistency or some form of event listening should be adopted?
The TicketFactory would be declare that in order to create a Ticket you need references to both a Department and an Employee. It would not verify that those actually exist. It would be the responsibility of the calling code to obtain the appropriate references.
If using eventual consistency, the decommissioning of a Department and Employee would publish events indicating the decommission. There would be a handler associated with a Ticket which would subscribe to that event and either assign a new department and employee or send some sort of warning to task.
Take a look at Effective Aggregate Design for more on this.
I've recently started exploring DDD, so I have ran into some of the issues you mention.
I think that TicketFactory should always return validated/properly built Ticket instances. If you model is complex, you can have a domain service that validates that a given Department or Employee can be attached to it and then the factory uses it. Otherwise, you can just put it all in the factory. But what comes out of the factory should be a proper ticket.
I'd say that if e.g. only Ticket knows about the other two, a domain service that uses the Department and Employee repos would get the job done. If the relationship is bidirectional, then you can utilize event sourcing. Also, if it's really a event that should be captured in your domain model, and has other consequences other than reshuffling tickets, you can attach one of the handlers to this event to be InvalidTicketHandler. But if it's a small scale thing, keep it simple, just have a domain service that maintains the invariants.
Sidenote: If the Department and/or Employee are aggregates themselves, then you can reference them within Ticket via their identifier (e.g. employee's company ID or ID-code of the department). In that way you'll achieve consistency easier as you will not cross consistency boundaries between different aggregates.
A FACTORY is responsible for ensuring that all invariants are met for the object or AGGREGATE it creates; yet you should always think twice before removing the rules applying to an object outside that object. The FACTORY can delegate invariant checking to the product, and this is often best. [Domain-Driven Design: Tackling Complexity at the Heart of Software]
A depends on question type, but from the look of it it seems like a great candidate for an application layer functionality, i wouldn't go for the event solution though cause i find it only suitable in between layers and not between objects in the same layer.

how to use codeigniter database models

I am wondering how the models in code ignitor are suposed to be used.
Lets say I have a couple of tables in menu items database, and I want to query information for each table in different controllers. Do I make different model classes for each of the tables and layout the functions within them?
Thanks!
Models should contain all the functionality for retrieving and inserting data into your database. A controller will load a model:
$this->load->model('model_name');
The controller then fetches any data needed by the view through the abstract functions defined in your model.
It would be best to create a different model for each table although its is not essential.
You should read up about the MVC design pattern, it is used by codeigniter and many other frameworks because it is efficient and allows code reuse. More info about models can be found in the Codeigniter docs:
http://codeigniter.com/user_guide/general/models.html
CodeIgniter is flexible, and leaves this decision up to you. The user's guide does not say one way or the other how you should organize your code.
That said, to keep your code clean and easy to maintain I would recommend an approach where you try to limit each model to dealing with an individual table, or at least a single database entity. You certainly want to avoid having a single model to handle all of your database tables.
For my taste, CodeIgniter is too flexible here - I'd rather call it vague. A CI "model" has no spec, no interface, it can be things as different as:
An entity domain object, where each instance represents basically a record of a table. Sometimes it's an "anemic" domain object, each property maps directly to a DB column, little behaviour and little or no understanding of objects relationships and "graphs" (say, foreign keys in the DB are just integer ids in PHP). Or it can also be a "rich (or true) domain object", with all the business intelligence, and also knows about relations: say instead of $person->getAccountId() (returns int) we have $person->getAccount(); perhaps also knows how to persist itself (and perhaps also the full graph or related object - perhaps some notion of "dirtiness").
A service object, related to objects persistence and/or general DB querying: be a DataMapper, a DAO, etc. In this case we have typically one single instance (singleton) of the object (little or no state), typically one per DB table or per domain class.
When you read, in CI docs or forums, about , say, the Person model you can never know what kind of patter we are dealing with. Worse: frequently it's a ungly mix of those fundamentally different patterns.
This informality/vagueness is not specific to CI, rather to PHP frameworks, in my experience.

Cocoa bindings: get old value upon change

I am writing a core data Cocoa application in which there are accounts and transactions (monetary). The account entity description contains a balance attribute. The transaction entity description has a relationship to an account.
I need the application to update account balances when transactions have their accounts set or changed. For example, if a transaction's account is changed from checking to credit, the balances of both checking and credit should be changed to reflect this.
The problem I am having is that I am unsure how to determine the transaction's old account so I can update its balance. I am using bindings.
Can anyone point me in the right direction?
I assume that the account entity has the inverse relationship to the transactions. (Apple strongly suggests you always have inverse relationships. So if you haven't, please set it up!)
Let's say you have a subclass Account of NSManagedObject for the account entity, and Transaction for the transaction entity.
Call the inverse relationship to transactions as transactions.
Then, when you change the account for the transactions, the inverse relationship is automatically updated by CoreData. So, all you have to do is to write a self-observation routine for transactions in Account so that the Account objects keep track of the balance themselves. I think it is more object-oriented-y to make Account objects to take care of themselves than changing the balance from the side of the Transaction object... although of course it depends on your taste.
To perform the observation, you use KVO. Basically, you register the KVO by addObserver:forKeyPath:options:context: with a suitable set of options. Then, you get the change by implementing observeValueForKeyPath:ofObject:change:context:. The changes can be found in the dictionary passed to that method.

Resources