Difference between repositories and relations


I’ve started using ROM on a little side project, and I’m a little bit confused by all the concepts involved: containers, repositories, relations, structs… I’m starting to feel that plain Sequel is enough for my use case where 10 tables won’t turn into 40 Ruby classes. :slight_smile:

I’d like to understand better, when I’m supposed to use a repository to query a database, and when is it better to use a relation?


A good start point for understanding the difference is the brief concept definition found here https://rom-rb.org/5.0/learn/getting-started/core-concepts/#repositories

The way I use them is that I will have multiple repositories for the same relation in different parts of my domain that will fetch / save that relation as needed for the specific business flow.

The relation will contain all the schema definition and some of the common queries between all my business flows.

I want also to add that the idea of repository is essential, everything else rom can infer for you automatically, including relations, mappers, and structs. Repositories is where you map your domain entities to adapter-specific objects back and forth, at this point this cannot be done automatically in general but we have streamlined API for 1-to-1 cases.

Thanks for your replies. It helps getting some advice here, because the docs are almost all “this is automatic but you can also do it by hand”. I feel that there is not much guidance as to how all the concepts would click together, since every code example (for repositories or relations), show how you use those to make db queries… so I’m like, er… why do I need both then? :slight_smile:

I tend to think of it as this: the relation defines the structure, associations and views of some “dataset.” It’s mostly a specification or description.

The repository is the thing that actually uses the relations. Running queries, adding records, etc.

I still think the distinction is blurry though. It seems strange to me that it explicitly inherits functionally from a relation ( ROM::Repository[:posts]). Is the main purpose of that for making it easier to use?

@ianks what functionality?

I guess functionality might not be the right word, but a repo is tied to a relation inherently ROM::Repository[:users]. Makes it hard to understand the distinction for a repo and a relation for newer folks.

I can see some confusion here. No repo is not tied to any relation. The reason why “root repositories” were introduced is because it’s very, very common, to use a single relation as “the starting point” from which you get the data. That’s why it was beneficial to create a simple abstraction for such use case.

Repositories have access to all relations. The fact you typically use a single one as your “root” in aggregates is the reason why we have root repos. This allows you to do things like use root method in abstract way to add additional functionality (like “default scope” etc.).

I will try to explain this better in the docs. Thanks for feedback :heart:

1 Like