brettbeatty

brettbeatty

Ecto schema create assoc without adding to struct

Central to my app is the Account. I have a lot of schemas that belongs_to Account. I like including corresponding has_one/has_many on Account for query/build_assoc conveniences, but I don’t want to clutter the Account struct with an increasing number of non-core associations that will always be #Ecto.Association.NotLoaded<...>. Is there a way to define an association without adding it to the schema struct?

Off the top of my head the features I would most want but so far have worked around would be these:

  • join: m in assoc(a, :my_assoc)
  • Ecto.assoc(account, :my_assoc)
  • Ecto.build_assoc(account, :my_assoc)

First Post!

krasenyp

krasenyp

I don’t think there’s a way to do that. But your problem could be a symptom of non-optimal design.

Most probably, the problem is the Account schema being central to your app. One solution is to embrace a domain-driven design approach and think of how to separate it in multiple schemas in different bounded contexts. For this you’d have to have deep knowledge of the business domain.

Another approach is to stop relying on Ecto schemas everywhere in your app. They’re a database and/or validation concern. You could use well defined maps coupled with specs. Then you’d care more about the shape of your data and non-core fields won’t bother you that much.

I’m sure you’ll find a satisfactory solution.

Most Liked

fuelen

fuelen

You can hide fields you’re not interested in by defining Inspect protocol

@derive {Inspect, optional: [:my_assoc1, :my_assoc2]}

The code above will hide default #Ecto.Association.NotLoaded<...> values for :my_assoc1 and :my_assoc2 fields and will show them only if something else is set.

Last Post!

brettbeatty

brettbeatty

I appreciated your feedback and ended up going another way, but just to see if what I wanted was technically possible, I made it work in dev by overriding Account.__schema__/2 to support associations that don’t show up in the struct.

  defoverridable __schema__: 2

  def __schema__(:association, :my_assoc) do
    %Ecto.Association.Has{
      cardinality: :one,
      field: :my_assoc,
      owner: __MODULE__,
      related: MyApp.MyContext.MySchema,
      owner_key: :id,
      related_key: :account_id,
      on_cast: nil,
      queryable: MyApp.MyContext.MySchema,
      on_delete: :nothing,
      on_replace: :raise,
      where: [],
      unique: true,
      defaults: [],
      relationship: :child,
      ordered: false,
      preload_order: []
    }
  end

  def __schema__(arg1, arg2) do
    super(arg1, arg2)
  end

I have no plans to use this in production, but it does seem to work with Ecto.assoc(account, :my_assoc), Ecto.build_assoc(account, :my_assoc), and join: m in assoc(a, :my_assoc).

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42576 114
New

We're in Beta

About us Mission Statement