Embeds Vs. Associations

Hello Elixir/Phoenix Devs,

I have been reading about Ecto’s associations and embeds, I understand the difference between them. But I can’ t really tell when is which of them is better that the other.

For example let’s say we have a Class schema and Student schema. Obviously a class has_many students and the student belongs_to a class. Which is better to use here using associations or embeds and more importantly why?

Thanks in advance.

You would likely only want to use embeds in two cases:

  1. You will not have to share any of the embed structures with any tables. Which would not work at all if you wanted to have a Product embed in an e-shop, for example. But can very easily work if you make a money embed structure and just put something like %Money{currency: :EUR, amount_in_cents: 1137} in a field of your normal persisted Ecto model.

  2. You won’t do [complex] queries on the embeds. Again, if you want to be able to query products by color, adding date, prices etc., you are much better off them being a normal Ecto models and not embeds inside the order objects.

2 Likes

In general you want associations almost all of the time, if you do not have a particular use case where you know that you want to do something different and know exactly why you are doing it then you almost certainly should model your data relationally. There is on occasion a good reason not to and the hybrid model you get when you use json documents within a relational store means that you can take advantage of other options when required without having to make the same trade offs for your whole data model.

The main benefits you get with the embedded document (not an exhaustive list just a few key ones):

  1. it can be more flexible, the schema restrictions in this case only exist in your application and not the database, you can store some very loosely structured data if required
  2. if the embeded document is isolated from other data then you can get even a complex structure back out just by fetching a row

On the other hand, it can be much harder to perform many kinds of queries on embedded data, it doesn’t have relationships so updates usually mean updating the same data in multiple documents, it doesn’t have as much of a structure so you have to do more work to keep that structure sane at the application level and migrations that restructure those embeded documents require a lot more effort.

In the class example quite a bit of the detail that would really make huge amounts of difference in a decision is not really clear. Here are a few things that you could think about:

  • Can a student belong to both a Math class and a Physics class?
  • Do you frequently need to be able to query information about the students or only query about the class itself?
  • Is the student related to any data other than a class?
5 Likes

Thank you so much for the answer. Regarding the last 3 questions all of them is answered with YES. Now, I can tell that I will use association for such a case. Am I right?

Yes, definitely. As your parent commenter said, you want associations most of the time.

Embeds are a special case. You will know when you need them, be sure of it.

2 Likes

Yes that is correct, as @dimitarvp said you will know when the time is right to embed something, that time is very rare and has very specific requirements. If you answer yes to even one of the questions at the end then you need associations.

1 Like