chrisdel101
I have a Role like this in DB. It is attached to both a organization and a employee. But I cannot get both fields organization_id && employee_id to populate. This what it looks like after inserting an employee and an organization.
id | name | value | organization_id | employee_id |
----+-------+-------+-----------------+-------------+-
21 | owner | 1 | | 24 |
Modeling
schema "employees" do
has_many :roles, Role
schema "organizations" do
has_many :roles, Role
schema "roles" do
belongs_to :employee, Employee, foreign_key: :employee_id
belongs_to :organization, Organization, foreign_key: :organization_id
create table(:roles) do
add :organization_id, references(:organizations)
add :employee_id, references(:employees)
The problem is not with the modelling but with the actual insertion.
Here what I’ve tried but it’s not working. I always get the table at the top w/ a missing FK.
I try to
- associate the employee with the role then update the employee,
- associate the role itself with an organization and then update the org.
- Missing: associating the org with the role and upate the org.
Note: this is a bunch of random stuff trying to make the associations take. I know it’s not pretty.
def register_and_preload_employee(attrs) do
# build a role instance
role = Role{
name: "owner",
value: "1"
}
# build employee changeset
emp_changeset = Employee.registration_changeset(%Employee{}, attrs)
# assoc role with employee
emp_changeset = Ecto.Changeset.put_assoc(emp_changeset, :roles, [role])
#role is inserted
# Ecto.Changeset<
# action: nil,
# changes: %{
# email: "...
# ...
# roles: [
# #Ecto.Changeset<action: :insert, changes: %{}, errors: [],
# data: #Role<>, valid?: true>
# ]
# },
# errors: [],
# data: #Employee<>,
# valid?: true
# >
# get org and build_assoc foreign key
organization_id = 1
# get org and preload roles
organization = Company.get_organization(organization_id) |> Repo.preload(:roles)
# ATTEMPT to build assoc with org and role
role_w_org = Ecto.build_assoc(organization, :roles, role)
# org is loaded into role
# %Role{
# __meta__: #Ecto.Schema.Metadata<:built, "roles">,
# id: nil,
# name: "owner",
# value: "1",
# employee_id: nil,
# employee: #Ecto.Association.NotLoaded<association :employee is not loaded>,
# organization_id: 1,
# organization: #Ecto.Association.NotLoaded<association :organization is not loaded>,
# inserted_at: nil,
# updated_at: nil
# }
# insert employee
case Repo.insert(emp_changeset) do
{:ok, new_emp} ->
#preload in case required
emp_preload =
Repo.preload(new_emp, :organizations)
|> Repo.preload(:roles)
# ATTEMPT build assoc with org and role
role_loaded = Ecto.build_assoc(emp_preload, :roles, role_w_org)
# both foreign keys here
# %TurnStile.Role{
# __meta__: #Ecto.Schema.Metadata<:built, "roles">,
# id: nil,
# name: "owner",
# value: "1",
# employee_id: 24,
# employee: #Ecto.Association.NotLoaded<association :employee is not loaded>,
# organization_id: 1,
# organization: #Ecto.Association.NotLoaded<association :organization is not loaded>,
# inserted_at: nil,
# updated_at: nil
# }
# try to update role via employee update - role_loaded is not holding
update = update_employee(emp_preload) #-> Repo.update(...)
#AND/OR
# try to update role via organization update since it's preloaded
update_organization(organization) #-> Repo.update(...)
end
end
I guess maybe my issue is not understanding where the “child” actually gets inserted (not just in elixir, but in any FK relationship). Since the child Role is not actually inserted by me.
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
So i have been using ash framework for a while and i love it. However currently the issue im having with ash framework is the error handl...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex










Showing Posts 1 to 7- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
al2o3cr
What do you mean by “
role_loadedis not holding” here? There’s no connection betweenemp_preloadandrole_loaded.It’s hard to say with certainty without the code for these, but neither one takes
role_loadedas an argument so it’s not going to have an effect on them.What happens if you do
Repo.insert(role_loaded)?chrisdel101
It all comes down to this:
I don’t really understand how the associated object gets inserted. I don’t have a
Repo.insert(role)manually anywhere (other than than the one U just suggested).Repo.insert(role_loaded)does fix the issue sort of. But if I leave everything else as it I end up w this after: 2 instances of the same role.Basically the organization is already inserted and I need to fetch it, and add the role. While the employee is being created here along with the role.
Since this is so hard to do I’ll prob remove the 2nd foreign key constraint
organization_idand just add this manually to Role and have no connection to Organization.jswanner
One thing I don’t have a good sense of in your situation is what data is user provided (and therefore untrusted) or application provided, especially when it comes to roles (
nameandvaluefields). If the data is user provided and you’ll want to repopulate a form if a changeset is invalid, then you’ll most likely want to use cast_assoc/2 to set theroleson the employee, otherwise put_assoc/3 can be used.al2o3cr
There’s no need to give up, things aren’t THAT bad!
You will always get better results with questions about Ecto if you are specific about what you are trying to do. In particular, this is important:
This specific task is alternatively phrased as “I want to insert an employee and also create a role associated to an existing organization”, which then translates to Ecto operations:
You might also refactor this to make
Employee.registration_changesettake anOrganizationand do theput_assocthere, to keep things tidy.GazeIntoTheAbyss
How are you actually trying to insert the data?
If the process involves the creation of the employee then its pretty easy as you already have acess to their id in the process. Create a form with a dropdown/text input for the organisation_id in the employee creation form. Obviously display the name if its a dropdown rather than an ID.
For the organisation_ids, if they already exist and you want a selector for them you need to figure out the new way of doing something like this:
When you create the employee, do so in a case statement like this. You can take the organisation_id from the params, then after the employeee is created you can get the employee’s ID alongside the the organisation_id and just create a new role
Its just a basic example as I don’t know what kind of params you want the employee to have, but if you do this you can access the organisation_id from the form and you can access the newly created employees ID from the {:ok, employee}
The only other step is to add them as cast values in your changeset
chrisdel101
After running this I’m still missing theorganization_idlike the table in the original post shows. Maybe I have it wrong - when I createOrganizationbefore this (getting passed in asorganizationhere) there is noRoleassociated with it. I guess that is wrong.Or is the linerole = Ecto.build_assoc(organization, :roles, name: "owner", value: "1")supposed to handle this?Updated: The issue was that I was using using
build_assocon anOrganizationstruct from before it was inserted i.e not usingRepo.get(), so it was not associated with an existing record. Seems to be working now!chrisdel101
Yes! Using @jswanner solution which is the same as yours I got it to work.
I was not associating it properly with the organization. I have an idea how this associated insert works now.
A brief outline of how it works for my own future reference:
organization(parent 1) and insert into DB.organization(usingRepo.get()) to a create employee functionbuild_assocto link arole(child) with theorganizationemployee(parent 2) with a changesetput_attrto link therolewith theemployeerolewas linked to theorganizationbefore, now all 3 are linkedemployeeandrolewill automatically be inserted, and have both FKs.Thanks @al2o3cr !!