I'm currently re-implementing part of a Laravel(PHP) codebase in Elixir
where I had used the repository pattern
<http://blog.gauffin.org/2013/01/repository-pattern-done-right/> in only
some of the data models. In the Elixir implementation, I'd like to use it
across all the data models mainly because
1. I can swap out the implementation within tests
2. I can swap out the implementation to e.g. go through a cache layer for
reads
3. I want to able to use different ecto repos for e.g. read and write and
having abstract repositories would allow this to be done from a central
place
I worked on an initial implementation this weekend that works like this.
For each data entity, implement a "behaviour" with callbacks for that
particular entity e.g. a UserRepository where you need to query for a list
of active users would look like this
defmodule UserRepository do
use Repository.Base, # parses opts and config and sets @repository to
configured repository module
otp_app: :my_app
repository: MyApp.Repositories.EctoUserRepository # this points to the
concrete implementation and should be set within the config
@callback save(Ecto.Changeset.t) :: {:ok, User.t} | {:error,
Ecto.Changeset.t}
@callback get_active(non_neg_integer, non_neg_integer) :: [User.t]
end
The Ecto backed repository implementation would look like this
defmodule EctoUserRepository do
use Repository.Ecto.Base, # parses the opts and config, sets @repo and
@read_repo and implements a save function thats common to all Ecto repos
repo: MyApp.Repo,
read_repo: MyApp.Repo # could set a different repo for reads
@behaviour UserRepository
import Ecto.Query, only: [from: 2]
def get_active(offset, limit) do
(from u in User,
where: u.active == true,
offset: ^offset,
limit: ^limit)
|> @read_repo.all()
end
end
Please share any thoughts on this.
Now this is where I need some help, I want to able to use the repository as
UserRepository.get_active(0, 20)
what I've done at the moment is redefine each function within the
UserRepository and delegate to whatever repository is configured
defmodule UserRepository do
...
@callback save(Ecto.Changeset.t) :: {:ok, User.t} | {:error,
Ecto.Changeset.t}
@callback get_active(non_neg_integer, non_neg_integer) :: [User.t]
def save(changeset) do
@repository.save(changeset)
end
def get_active(offset, limit) do
@repository.get_active(offset, limit)
end
end
I find that this is quite repetitive and forces the same for all repository
implementations and functions.
--
You received this message because you are subscribed to the Google Groups
"elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-talk/47df7f07-0e79-40d7-b551-86839dba22b3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.