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

beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; somethi...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
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
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New

Other popular topics Top

axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48342 226
New
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
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43757 214
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
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
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement