Answers to your numbered questions
1 . Why don't you have business logic in your business model / objects?
Are these relationships and behavior, after all, one of the goals of object orientation? I believe that you may have misunderstood the concept of “ POJO (and I'm not talking about J standing in Java;)), the purpose of which was to prevent frameworks from invading your model, thereby restricting the model to context specific for structure, and makes unit testing or reuse difficult in any other context.
What you're talking about is more like DTOs , which is usually not the one your model should consist of.
2 : Yes, Twig doesn't manipulate numbers very well, which symbolizes meaning. You will probably get all kinds of offers based on things like storage optimization (number of bytes) or database traffic / query time, but for most projects I prefer the priority of human experience - i.e. do not optimize for computers if you do not need it.
Thus, my personal preferences (in most cases) are instantly decryptable fields "enum", but in a key form instead of ordinary words. For example, "status.accepted" as opposed to 1 or "Accepted" . Key-like notations lend themselves well to i18n, using the twing |trans filter, {% trans %} tag or something similar.
3 . Static "enum" links within your model are rarely a problem when unit testing the model itself.
At some point, your model should define its semantics anyway, using the building blocks you have available. Although the ability to abstract from implementations (in particular, services) is useful, the ability to abstract from meaning is rarely (never?) Fruitful. Which reminds me of this story. Do not go there.: - D
If you are still concerned about this, put the constants in an interface that implements the model class; then your tests can only refer to the interface.
Recommended Solution
Model Alternative 1:
class Booking { const STATUS_NEW = 'status.new'; const STATUS_ACCEPTED = 'status.accepted'; const STATUS_REJECTED = 'status.rejected'; protected $status = self::STATUS_NEW; }
Model Alternative 2:
interface BookingInterface { const STATUS_NEW = 'status.new'; const STATUS_ACCEPTED = 'status.accepted'; const STATUS_REJECTED = 'status.rejected';
Twig:
Status name: {{ ("booking."~booking.status)|trans({}, 'mybundle') }}
(Of course, the booking. Prefix is optional and depends on how you want to structure your keys and i18n files.)
Resources / Translations / mybundle.en.yml:
booking.status.new: New booking.status.accepted: Accepted booking.status.rejected: Rejected
Constant-like-objects
In Tomdarkness, the proposal to include these constants in their own model class, I want to emphasize that this should be a solution for the business / domain, and not a question about technical preferences.
If you clearly anticipate the use cases for dynamically adding statuses (provided by users of the system), then, of course, the right choice is the model / entity class. But if the statuses are used for the internal state of the application, which is related to the actual code that you are writing (and therefore will not change until the code changes), you are better off using constants.
Entity constants make working with them much more difficult ("hm, how can I get the primary key of the" accepted ", again?"), It is not so easy to internationalize ("hm, I store possible locales as hard-coded properties in the ReserveStatus entity, or I I’m doing another OrderStatusI18nStrings (id, locale, value)? ") object, as well as the refactoring problem you came up with. In short: don't relearn - and good luck .; -)