First to set the stage. Say we have an app that represents a Shop that sells Books amongst other things. Books have differential pricing. So we have chosen to design DB schema as two tables. Books and BookValues with 1 to many relationship. With Ecto we will get a schema struct which is something like
This is one of those big ol’ “it depends” questions (emphasis on “big ol’” since technically the answer to any question is “it depends”).
While I feel you’d just like me to take your example at face value, I think in this case more details are required. I see a book has multiple prices, but what are these prices based on? Are they categorical (like good, fair, poor)? Does two or more books having the same price have any other meaning other than they just cost the same?
I am generally not concerned about heavier JSON payloads but the above questions still stands. If prices are simply just a number, I wouldn’t even bother modelling them—just return prices: [10.0, 12.30] as a list of primitives. If prices have more to them than that I think you have to answer the question: “Do books without prices make sense?” If not, always return a list of prices; if so, don’t.
Also, I’m realizing I’m assuming you’re talking about a REST API here? I’m not actually sure. I’m so entrenched in LiveView at this point that I don’t really think about JSON payloads anymore and have been reframing your question a bit in terms of schema vs embedded_scehma, but your question stuck a chord so I thought I’d try and help!
Thank you for taking time to discuss about this. Yes prices are simply that just floats for now. Indeed in ShopWeb box I should have included an embedded_schema struct. But in this case it would likely be the same as domain struct.
But potentially there could be a case where we want to somehow return a JSON payload that requires massaging of the domain struct and that’s where embedded_struct will come in.
Well I think you have to still answer if there is any categorical meaning to prices or if they are simply prices. Maybe that is what you are saying? But, to say something very general and boring about programming: I would never take “potentially” into account—Always do the simplest thing you can get away with right now. You can’t predict the future so don’t prepare for it (note: I’m scoping this claim purely to software dev ). Of course, if this is just a hobby project and you’re looking to learn it’s a different story, but in that care I still have my litany of questions!
But because they are just floats right now (though I would urge you to use either Decimal or integer stored as cents) I would just make prices a list of floats (primitives). This is so dead simple that if-and-when your needs change it will be much easier to refactor than if you prematurely try and model prices upfront.
two short unrequested comments that don’t answer your question but may help.
As mentioned by @sodapopcan, never use floats for money. Binary floating point is an imprecise representation of decimal numbers, and you want your money amounts to be correct to the last cent. Always use arbitrary precision libraries like Decimal.
Keep the names in your code simple and close to the actual model: don’t name it BookValue, use BookPrice instead.