tadasajon
Should I add belongs_to to my schema? What do I gain?
I have added users to my Phoenix application through phx.gen.auth and I have the following schema defined in lib/myapp/accounts/user.ex:
schema "users" do
field :email, :string
field :password, :string, virtual: true, redact: true
field :hashed_password, :string, redact: true
field :confirmed_at, :naive_datetime
timestamps()
end
Now I’m expanding my app and adding a catalog of products – and I want to make sure that each product has a maker in my system, which should correspond to a user from the accounts context. So I ran the following Phoenix generator:
mix phx.gen.html Catalog Product products url:string:unique product:map maker_id:references:users
This is the migration that was generated:
def change do
create table(:products) do
add :url, :string
add :product, :map
add :maker_id, references(:users, on_delete: :nothing)
timestamps()
end
create unique_index(:products, [:url])
create index(:products, [:maker_id])
end
and this was the schema that was generated in lib/myapp/catalog/product.ex:
schema "products" do
field :product, :map
field :url, :string
field :maker_id, :id
timestamps()
end
I wanted to make sure I could not add a product to my system without associating it with a user, and that deleting a user would delete all their associated products, so I adjusted the migration to add null: false and on_delete: :delete_all to the maker_id.
add :maker_id, references(:users, on_delete: :delete_all), null: false
So I should now have a solid foreign key for every product that will point to the users table.
Here are a few questions I have:
-
Why didn’t the generator automatically add a
belongs_tomacro to my products schema? It should know that the maker_id is a foreign key pointing to users, so it ought to have known how to do this. -
How will my app benefit if I adjust the products schema by adding the
belongs_tomacro? The relationship is already constrained in Postgres, after all. -
Do I need to add a corresponding
has_manymacro to my users schema? What do I lose if I don’t? -
Is this the correct way to specify
belongs_tofor the situation I have described:
schema "products" do
field :product, :map
field :url, :string
belongs_to :user, Myapp.Accounts.User, foreign_key: :maker_id
timestamps()
end
- Should I set the
:sourceoption, which is mentioned in the docs? Ecto.Schema — Ecto v3.14.0
Thanks!
Most Liked
dimitarvp
I can’t answer all your questions well so I’ll respond to the title and a part of them:
Add those macros only if you need a back-reference to the owning object in your code, and if the owning object needs to know all the object it owns / points to. In the past I’ve commented out various belongs_to and has_many statements if after analysis I found I don’t use them.
However, with time I preferred to leave them in because they are not introducing a noticeable load on the DB and their presence serves as good DB design documentation.
50/50, nowadays I lean to leaving them in even if I don’t use them but I can see why people would comment them out (or skip them altogether) as well.
christhekeele
I often find myself using belongs_to back refs during debug console sessions, so I like to leave them around since it impacts little else.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









