benonymus

benonymus

How to get team name based on team id in an entity from another table?

Hey I have a user entity in my postgres database and I am displaying it with the generated index method:

  def index(conn, _params) do
    users = Web.list_users()
    render(conn, "index.html", users: users)
  end

I have a field in it called teamid that is based on a selected team when the user is created.
how could i get the team name from another table based on the teamid? when i log out the user it looks like this:

[
  %Userteam1.Web.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 6,
inserted_at: ~N[2018-08-11 07:29:21.552256],
name: "ssd",
password: "dssd",
teamid: "1",
updated_at: ~N[2018-08-11 07:29:21.557296]
  },
  %Userteam1.Web.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 7,
inserted_at: ~N[2018-08-11 07:30:25.431934],
name: "kkjkj",
password: "kjkjjk",
teamid: "2",
updated_at: ~N[2018-08-11 07:30:25.436358]
  },
  %Userteam1.Web.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 8,
inserted_at: ~N[2018-08-11 07:42:05.148300],
name: "tr",
password: "tr",
teamid: "2",
updated_at: ~N[2018-08-12 06:07:00.772189]
  }
]

Marked As Solved

Ryzey

Ryzey

I have fixed the web part of the app in my forked version.

  1. I updated the web schemas with the changes I made earlier to the other schemas (I didn’t realize at first that your use of duplicate schemas was intentional);
  2. I updated list_users/0 to preload the teams field;
  3. Updated any display of teamid in the templates to team.name
  4. Updated the <select> element for team to reference team_id

It seems to be working well.

EDIT: Note that even if you want to use 2 schemas for User and 2 schemas for Team, each should still only have one migration as the duplicate schemas will be referencing the same db table. Currently you seem to have 2 migrations for each.

Also Liked

Ryzey

Ryzey

If Ecto knows about how the two schemas are associated, then it will be able to automatically join the tables in queries when you include a preload instruction.

So, if you:

  1. Add has_many(:users, Userteam1.User) to your team schema;
  2. Add belongs_to(:team, Userteam1.Team) to your user schema;
  3. Remove the teamid field from the user migration;
  4. Add add(:team_id, references(:teams)) to your user migration;
  5. Replace :teamid in your user changeset cast and validate_required params to :team_id

then you should be able to get all users with team names as follows:

from(User, preload: [:team])
|> Repo.all()

I haven’t tested this code, so it’s not guaranteed to work, but it should point you in the right direction.

Ryzey

Ryzey

Note that you should only have one schema module for User and one for Team, so somehow these have been duplicated in your project (maybe by running the generators twice?). Your migrations are duplicated as well. It will be simpler to have the migration for Team run before the migration for User as one of the fields in User relies on the Team table existing (otherwise you will need a third migration that amends the User table after the Team table has been created). You can try to delete the duplicate files, or maybe it’s easier to start again?

If your user is setup like this:

defmodule Userteam1.User do
  use Ecto.Schema
  import Ecto.Changeset

  schema "users" do
    field(:name, :string)
    field(:password, :string)
    field(:role, :string)
    belongs_to(:team, Userteam1.Team)
    timestamps()
  end

  def changeset(user, attrs) do
    user
    |> cast(attrs, [:name, :password, :role, :team_id])
    |> validate_required([:name, :password, :role, :team_id])
  end
end

then it will have a team and team_id field:

iex(1)> %Userteam1.User{}
%Userteam1.User{
  __meta__: #Ecto.Schema.Metadata<:built, "users">,
  id: nil,
  inserted_at: nil,
  name: nil,
  password: nil,
  role: nil,
  team: #Ecto.Association.NotLoaded<association :team is not loaded>,
  team_id: nil,
  updated_at: nil
}

and if your team is setup like this:

defmodule Userteam1.Team do
  use Ecto.Schema
  import Ecto.Changeset

  schema "teams" do
    field(:name, :string)
    has_many(:users, Userteam1.User)
    timestamps()
  end

  def changeset(team, attrs) do
    team
    |> cast(attrs, [:name])
    |> validate_required([:name])
  end
end

then it will have a users field:

iex(2)> %Userteam1.Team{}
%Userteam1.Team{
  __meta__: #Ecto.Schema.Metadata<:built, "teams">,
  id: nil,
  inserted_at: nil,
  name: nil,
  updated_at: nil,
  users: #Ecto.Association.NotLoaded<association :users is not loaded>
}

For this to work with the db, your migration for users should look like this (provided the migration for teams is before the migration for users, otherwise you will need to have two migrations for users with an alter table instruction in the second one):

defmodule Userteam1.Repo.Migrations.CreateUsers do
  use Ecto.Migration

  def change do
    create table(:users) do
      add(:name, :string)
      add(:password, :string)
      add(:role, :string)
      add(:team_id, references(:teams))

      timestamps()
    end
  end
end

I forked your project on Github, made the changes above, and it worked okay.

dimitarvp

dimitarvp

Meaning what exactly? Does not the excellent Ecto documentation help?

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New

Other popular topics Top

peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement