3

In most MVC web projects there is a User class. Many times a user has something else in a one-to-many relationship, i.e. orders.

If we have a user class that has many orders, should methods that add, edit or delete orders for a user be placed in the user class, or in a separate Order class?

i.e.

1.

user.add_order(order_name) //Instance method

vs

2.

Order.add_order_for_user(user_id, order_name) //Static method

or alternatively,

3.

order = new Order(user_id,order_name)
order.save()

(Also, in the case of option 3, should this be combined with option 1 and put in that method)?

My main issue with option 1 is that the user model tends to get huge in terms of size. Does this violate SRP? For instance, in one of my projects a user has many "things" like friended users, feeds, uploaded files, warnings, punishments, and the list goes on. I'm basically adding CRUD methods for all those "things" that a particular user has many of, in the User class itself. Is this a bad thing, and should I spread out the CRUD methods to different classes?

However, one of the advantages for option 1 is that I can control logic in those CRUD methods using the attributes of the current user object, without having to query the user. For instance, if I have a method "add_file" I can check to see if the user's total file space used (an attribute of User) is less than a max without having do do another query.

asked Apr 18, 2014 at 2:25
2

2 Answers 2

1

Generally all nouns should have their own class, a model in the case of using the mvc pattern. User and order are two separate things so you should have two models. However, they are related so your data model should have a key or bridge table to relate users with orders. A user has orders but a user is not updated from an order but more precisely an order record is updated, so you'd want to use the order model for your crud operations.

The problem with scenario 1 is that your code will be tightly coupled to a user.

Also, looks like you should be passing in the order id and user id, not the order name to maintain good practices using proper constraints.

answered Apr 18, 2014 at 3:29
1

If your case is order processing which is focusing in orders, then I believe Order is the root aggregate entity that has a reference to User entity, for example:

class Order {
 User user 
 Payment payment
 Delivery delivery
 ...
}

If you want to select Order based on User, you can create new methods in your repository such as:

interface OrderRepository {
 public List<Order> findOrderByUser(User user); 
 public List<Order> findOrderByUserAndStatus(User user, OrderStatus status);
}

If you have business logic that requires some calculations in User based on Order, you can add required Order to User. Usually it is not all Order that has been created by that user (your concern is they are too many to store in User, right?). For example, it can be pendingOrder:

class User {
 List<PendingOrder> pendingOrders = []
 BigDecimal creditLimit
 boolean allowNewOrder() {
 ... // check if sum of pendingOrders is not more than allowed limit
 }
}

I believe this will make your domain classes richer.

answered Apr 18, 2014 at 7:21

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.