How to get associated values from a preloaded object help me please

Please help me as this will help me land a job
i want to get values from a preloaded to render

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

i got my data here

  def list_users do
    Usermanagement.Management.User
     |> Repo.all()
     |> Repo.preload(:tags)

  end

then i want to pass it here in this view i saw in cmd that the query has been done

  def render("user.json", %{user: user}) do

    %{id: user.id,
      name: user.name,
      country: user.country
  ----->>pass tag.name here which is associated 
     }

  end

ive tried user.tags.name this is the error

[%Usermanagement.Management.Tag{__meta__: #Ecto.Schema.Metadata<:loaded, "tags">, id: 1, inserted_at: ~N[2018-02-02 08:42:54.738000], name: "Games", typeone: "Sample Type 2", typetwo: nil, updated_at: ~N[2018-02-02 08:42:54.742000], users: #Ecto.Association.NotLoaded<association :users is not loaded>}]

user.tags is a list. You should do

tags: Enum.map(user.tags, &tag_to_json(&1))
...
defp tag_to_json(tag) do
  %{name: tag.name}
end
1 Like

hi thanks for this i do have two another question
1.)Tag table has fields name , typeone,typetwo how do i get those other two ive tried
def render(“user.json”, %{user: user}) do

%{id: user.id,
name: user.name,
country: user.country,
tagname: Enum.map(user.tags, &tag_to_json(&1)),
tagtype: Enum.map(user.tags, &tag_to_json(&2))

}
end

defp tag_to_json(tag) do
%{name: tag.name,typeone: tag.typeone

}
end

Second question is
the output is
{“data”:[{“tagname”:[{“name”:“Games”}],“name”:“Berlyn”,“id”:1,“country”:“PH”}]}
can i possibly make it like tagname only no name inside

You cannot call tagname on the list, but on each element of it :slight_smile:

i cant understand what does it mean :cold_sweat:

Your relation between user and tags is belong_to/has_many or many_to_many. A user can have many tags.

A user structure will load a user, and a list of associated tags.

You have to treat tags as a collection, not as an individual element. What is tagname in your example? is it the name of the first tag? tagnames would probably fit, but not tagname.

|> Repo.all()
|> Repo.preload(:tags)

so that means Repo.all() shows all users as single
Repo.preload(:tags) shows all tags related to users

btw this is the structure of my table

User

id PK
name

Tags

id PK
name

Taggables

id PK
user_id FK of user table
tag_id FK of tag table

The Taggable model keeps many-to-many relationships between User and Tag.

so that means tag_to_json function creates a new object?

does it mean i need to create tag_to_json(tag) for every field of tag model

tag_to_json is a function that takes a tag and transform it into its json representation.

Enum.map(user.tags, &tag_to_json(&1))

This line will take all tags related to a user, and render it as json, that would be

%{id: 1,
  name: "koko",
  country: "here",
  tags: [%{name: "tagname1", type: "tagtype1"}, %{name: "tagname2", type: "tagtype2"}, ...]
}

Thank you very much , i’ve been struggling for this for hours.now i understand it. :grinning: :slight_smile:

Cool, good luck for your job :slight_smile:

BTW Try to avoid using model and object at the interview, use schema, module, function, argument instead :wink: