Using Ecto v2.2.6, Phoenix 1.3
I am trying to seed a linking table created with phx.gen.json
.
First, a simple linking table. I create a User model, a Groups model, and a linking table that joins them with a many-to-many relationship.
Primary tables:
mix phx.gen.json Account User users email:string
mix phx.gen.json Account Group groups name:string
For users_groups, I create a migration and a schema without phx.gen
Migration:
create table(:users_groups) do
add :user_id, references(:users)
add :group_id, references(:groups)
timestamps()
end
# indexes here
Schema:
schema "users_groups" do
belongs_to :user, MyApp.Accounts.User
belongs_to :group, MyApp.Accounts.Group
timestamps()
end
I add many-to-many
relationships with the User and Group schemas, and then I seed them like this:
Repo.insert!(UsersGroups.changeset(
%UsersGroups{}, %{
user_id: 1,
group_id: 2
}
))
It works great; the associations go in and I can see my many-to-many relationships.
However, if I create the linking table with something like this:
mix phx.gen.json Accounts UserGroup users_groups user_id:references:users group_id:references:groups
...and try the same approach to seeding, I see this:
%MyApp.Accounts.UserGroup{__meta__: #Ecto.Schema.Metadata<:loaded, "users_groups">,
id: 1, inserted_at: ~N[2017-10-07 19:36:34.095408],
group: #Ecto.Association.NotLoaded<association :group is not loaded>,
group_id: nil, updated_at: ~N[2017-10-07 19:36:34.095411],
user: #Ecto.Association.NotLoaded<association :user is not loaded>,
user_id: nil},
What is happening, and what do I have to do to seed this new entity?
By default, the generated changeset functions do not include associations in the cast
call 1 2 3, which means they're ignored by the changeset function. You'll need to add these columns yourself to the cast
call.
In lib/my_app/accounts/user_group.ex
, change:
def changeset(%UserGroup{} = user_group, attrs) do
user_group
|> cast(attrs, [])
|> validate_required([])
end
to:
def changeset(%UserGroup{} = user_group, attrs) do
user_group
|> cast(attrs, [:group_id, :user_id])
|> validate_required([:group_id, :user_id])
end
and the seed function should now work.