Choose relation one to many or many to one for design - relation

I need help to define the relationship between the models.
I have 2 models :
User
Product
The user own many products and the product is owned by only one user.
My use case :
The logged user can access to some information in his personnal account :
- Display all his products
- Add a new product
Later i'd like to add use case like : any user can see any product in some screen (and know product's owner).
So, i can define the models like that :
A) ONE TO MANY
class User{
private Set<Product> products;
..
}
class Product{
...
}
B) MANY TO ONE
class User{
..
}
class Product{
private User owner;
}
Which is the best ? one to many or many to one ?
Because my use case display the product of logged user Im thinking its better to choose one to many

The most likely option for this would be One To Many as a User owns products. He has products (so a list of them). In the second option you would say: a product owns a user.
As for the requirements:
Display all his products
Will you display all his products or will you display all products that have the user as owner.
Add a new product
The user adds a product to his list compared to a product adds the user as an owner.
The last requirement is quite tricky: "any user can see any product in some screen (and know product's owner)". Now if this is the main functionality the second design would be better as it would be easier finding the owner from a product. Though the use case description seems to be quite focussed on the One to Many design.

Related

Handle model dependencies in Laravel Repository Pattern

I'm discovering the Repository Pattern for my Laravel project but I have to say that I'm a bit lost once a model has several dependencies and the examples on the web are always basic and don't answer the question for more complex use cases.
Let's imagine a user on my app. He can have badges, he has different things on the app that will be slightly modified when he first performs the action (when he first sees the comments, I tell him once the different things he can do, etc), he has several "counters" to record the number of comments he made, the number of friends he invited, without having to count each entry each time.
My database looks like this:
users table:
id
pseudo
name
password
...
badges table:
user_id
badge1_xxxxxx
badge2_xxxxxx
...
I have a very limited number of badges so I decided to create a column for each of them and as soon as a user wins a badge, I get his entry (in OneToOne relationship) and I indicate that the badge in question has been won.
onboarding table:
user_id
seen_comments (boolean)
seen_results (boolean)
...
As you can see, I store each action I'd like the user to do in different columns and as soon as he has done one and I've been able to modify my app accordingly (by showing him an arrow, etc), I put the column in question to true.
user_counters table:
user_id
count_comments
count_invited_friends
...
I don't consider a user to be a user if he doesn't have an entry in each of the tables (I could have done everything in one table but the users table seemed to me to become huge). The only relationship used is OneToOne between the user and the table in question.
Should I do this ?
class UserRepository {
public function register($data) {
// Create the user
$user = User::create($data);
// Create all its dependencies which are required if I want to consider the user as fully registered in my DB
$user->badges()->create();
$user->onboarding()->create();
$user->counter()->create();
// Return the user
return $user;
}
}
Or should I create a Repository for each of these elements and create the entire user in a UserService ?
How far should I separate things and when does it become overkill?
Is there something that I don't understand in concept of Repository ? If so, could you give me some links that you found useful because I feel like I ran out of ideas for search keywords.
Thanks

Coupling in microservices architecture

When working on an application in microservices architecture I stumbled upon issues concerning coupling between services.
This a typical application for ordering products. It seams reasonable to have a service that will operate as a product catalog. Our JavaScript client can ask this service for available products and show them in browser. When user clicks on a product we have to create an order. We would like to manage orders in another service. So an order is created - it means that user X ordered product Y. On the technical level we are simply persisting user id and product id in a database.
To sum up we have:
Products service
Product class:
Product ID, Product Name
Orders service
Order class:
Order ID, Product ID, User ID, Order date
Now let's imagine following scenario - in JavaScript client we would like to list all products that user have ordered. Orders service provides a list of products ids for a given user. But user cares about product name, not the id. Unfortunately Orders service doesn't know anything about products names.
We could tackle this in couple of ways:
Simply assume that the client is responsible for getting the information it needs. So after it calls Orders service and gets a list of products ids, it performs another call to Products service, passing products ids and getting corresponding products names in response. Then the client assembles both responses into something useful. This approach keeps our services clean, without leaking of domain knowledge from one service to another. But it requires more work on the client side.
Orders service when asked for ordered products makes a call on the backend to the Products service. It retrieves product names, assembles a response that contains orderDate and productName and sends that to client. All that's left for client to do is to present the data. Downside of this approach is that Orders service now gains more knowledge about products than neccessary.
Duplicate information about product name in Orders service. When an order is created, we pass not only product id but also product name. That means that Order class will look like this:
Order class:
Order ID, Product ID, Product name, User ID, Order date
Now we can easly provide full information about order without additional call to Products service. Also this time Orders service has too much knowledge about products. What's beneficial tough is that Orders service can provide relevant data even if Products service is down.
Could any of these approaches be considered best practice? Or are there different solutions?
In the eShopOnContainers example( https://github.com/dotnet-architecture/eShopOnContainers ), they add the following fields at the time an order item is created:
public void AddOrderItem(int productId, string productName, decimal unitPrice, decimal discount, string pictureUrl, int units = 1)
This duplicates the catalog information, however as this is a point in time snapshot of the record. This is far safer than linking to the original data.
At this point in the user journey you are in the domain of an order, if a user is viewing an order you can provide a link to the catalogue. However, the order service should be able to operate independently. Linking back to the catalogue for the information on products prevents the Order service owning it's own data.
A nightmare scenario being that a price changes in the catalogue... What would happen to the historic orders?

Database schema for kind of Hospital Management in Laravel

I am trying to start an application but it's not for managing hospital, it will be for doctors and patients. Where there will be multiple types for users will be able to login such as Doctor, Patients/Guardians.
Doctors can have multiple clinics at multiple locations and doctor can manage patient records. Once the patient account has been created by doctor then patient can take appointment from doctor or update his appointment status and many more stuff will be there next.
The thing is how to go with the ERD?
I will have
User //User accounts used to login in to the system
Doctor
Patient
Guardian
Role
Permission
These are the models I have currently created, but they don't seem right to me.
Should I remove role columns as I already have different tables for different pre-defined roles?
Or should it be there? But how to manage permissions on users if no roles table is there?
Also, most importantly, how to go with one to one with users? I mean should I go and create functions in user model such as:
public function doctor(){}
public function guardian(){}
public function patient(){}
Or is there a better approach to follow?
If they are all users, you can extend different users from a base user model.
If they require different columns in database, consider single table inheritance.
If roles are static, I would create a class called UserType and have constants of each user type mapped to an integer. In the database, the user table will have a type column which is mapped to this integer.
For example:
class UserType {
const DOCTOR = 1;
}
In your application you'll be able to check the type of user by doing $user->type === UserType::DOCTOR
In the Eloquent itself, you can extend newFromBuilder method to check the type attribute and return the child class (like Doctor) instead of User. So even when you do $user = User::find(1);, you'll still get the class Doctor.
When creating users, you can just create Doctor itself but make sure in __construct to set the appropriate type attribute.
So now you have a base User class, your shared functionality can go here. Specialised methods such as relation to clinics can go in the Doctor class.
This is somewhat similar to the above: https://github.com/Nanigans/single-table-inheritance

Magento FPC and $_SESSION object

How to use a cache when you have content depending on SESSION variable?
Does it work with Varnish-like cache? Does it require FPC?
let me explain.
My customers can select their model of Car (manufacturer, model, year), once selected this is stored in SESSION object.
(Of course every product is linked to a list of Cars in the back end.)
The thing is, on the frontend, There is a module that automatically filters the products according to the Car selected by the customer.
I'm not only talking about a user that would search for a product by entering a keyword on the search bar.
I'm also talking about the category pages.
When the customer visits the website, clicking on a category, then the list of products within this category is filtered too!
So while the customer navigates, he only see compatible products with his car.
I failed to use VARNISH because of this (VARNISH is based on url only, and the selected Car is not part of every url...).
That's why I'm wondering if there is any concept of Cache that would take into account SESSION variables?
thanks,
Rod

Relate two entities via a third one

I am trying to figure it out how to relate two entities using another one they both have in common. My model is the following:
A Customer has a list of Codes
A Promotion has a list of Codes
A Code has a list of Customers and a list of Promotions
I would like to add to the Promotion Entity a list of Customers. This list would include all customers who at least have the same codes as in the promotion (can have more). Ideally I would like to model this a field but I am not sure if this is possible. I have found no information.
Can it be done?
Thanks,
You can define
Customer Entity.
Code entity which has #ManyToMany relationship with Customer. ( This is required if customer can have code even when there is no promotion.)
Promotion Entity which has #ManyToMany relationship with Customer
and #ManyToMany with Code.
At the end I ended up doing the following
public Set<Customers> getCustomers(){
Set<Customers> customers = null;
for (Code c : codes)
if(customers == null)
customers = c.getCustomers();
else
customers.retainAll(c.getCustomers());
return customers;
}
I do a Eager retrieve for the Codes, and in the codes an Eager retrieve for the Customers. So far is performing well, but I would prefer this to be all calculated in the DBMS and not on the controller side. Still have not find a nice way to to it.

Resources