Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h3>Answers to your numbered questions</h3> <p><strong>1</strong>: Why <em>wouldn't</em> you have business logic in your business model/objects?</p> <p>Coupling data and behaviour is, after all, one of the very purposes of object orientation? I believe you may have misunderstood the "<a href="https://en.wikipedia.org/wiki/Plain_Old_Java_Object" rel="nofollow noreferrer">POJO</a>" concept (and I'm not talking about the J standing for Java ;)), whose purpose was to not let <em>frameworks</em> invade your model, thus limiting the model to a framework-specific context and making unit testing or re-use in any other context difficult.</p> <p>What you're talking about sounds more like <a href="https://en.wikipedia.org/wiki/Data_transfer_object" rel="nofollow noreferrer">DTOs</a>, which generally is <em>not</em> what your model should consist of.</p> <p><strong>2</strong>: Yes, Twig is not terribly good at manipulating numbers-that-symbolizes-meaning. You'll probably get all kinds of suggestions based on things like optimization of storage (number of bytes) or database traffic/query time, but for most projects I prefer prioritizing the human experience - i.e. don't optimize for computers unless you need it.</p> <p>Thus, my personal preference (in most circumstances) is instantly dev-readable "enum" fields, but in a key-like notation instead of regular words. For example, <code>"status.accepted"</code> as opposed to <code>1</code> or <code>"Accepted"</code>. Key-like notations lend themselves well to i18n, using twig's <a href="http://symfony.com/doc/current/book/translation.html#translations-in-templates" rel="nofollow noreferrer"><code>|trans</code> filter, <code>{% trans %}</code> tag</a> or something similar.</p> <p><strong>3</strong>: Static "enum" references <em>within</em> your model is rarely a problem while unit testing the model itself.</p> <p>At some point your model needs to define its semantics anyway, through the use of the building blocks you have available. While being able to abstract away <em>implementations</em> (particularly of services) is useful, being able to abstract away <em>meaning</em> is rarely (never?) fruitful. Which reminds me of <a href="http://thedailywtf.com/Articles/It_Depends_on_Your_Definition_of_True.aspx" rel="nofollow noreferrer">this</a> story. Don't go there. :-D</p> <p>If you're still concerned about it, put the constants in an interface that the model class implements; then your tests can reference only the interface.</p> <p>&nbsp;</p> <h3>Suggested solution</h3> <p>Model, alternative 1:</p> <pre><code>class Booking { const STATUS_NEW = 'status.new'; const STATUS_ACCEPTED = 'status.accepted'; const STATUS_REJECTED = 'status.rejected'; protected $status = self::STATUS_NEW; } </code></pre> <p>Model, alternative 2:</p> <pre><code>interface BookingInterface { const STATUS_NEW = 'status.new'; const STATUS_ACCEPTED = 'status.accepted'; const STATUS_REJECTED = 'status.rejected'; // ...and possibly methods that you want to expose in the interface. } class Booking implements BookingInterface { protected $status = self::STATUS_NEW; } </code></pre> <p>Twig:</p> <pre><code>Status name: {{ ("booking."~booking.status)|trans({}, 'mybundle') }} </code></pre> <p>(Of course, the <code>booking.</code> prefix is optional and depends on the way you want to structure your i18n keys and files.)</p> <p>Resources/translations/mybundle.en.yml:</p> <pre><code>booking.status.new: New booking.status.accepted: Accepted booking.status.rejected: Rejected </code></pre> <p>&nbsp;</p> <h3>Constants-as-entities</h3> <p>On <a href="https://stackoverflow.com/users/1248820/tomdarkness">Tomdarkness</a>' suggestion of turning these constants into their own model class, I want to stress that this should be a business/domain decision, and <em>not</em> a question of technical preference.</p> <p>If you clearly foresee the use cases for <em>dynamically</em> adding statuses (supplied by the system's users), then by all means a new model/entity class is the right choice. But if the statuses are used for internal state in the application, which is coupled to the actual code you're writing (and thus won't change until the code changes too), then you're better off using constants.</p> <p>Constants-as-entities makes working with them much harder ("hm, how do I get the primary key of 'accepted', again?"), isn't as easily internationalizable ("hm, do I store the possible locales as hard-coded properties on the BookingStatus entity or do I make another BookingStatusI18nStrings(id, locale, value) entity?"), plus the refactoring issue you brought up yourself. In short: don't overengineer - and good luck. ;-)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload