2
votes

I have the following two models, User and Post. I am trying to create a post with a foreign key relation to a user.

My schemas:

@primary_key {:id, :binary_id, autogenerate: true}
schema "accounts_users" do
  field :username, :string
  field :email, :string
  field :password_hash, :string
  field :password, :string, virtual: true
  has_many :posts, Udia.Logs.Post

  timestamps(type: :utc_datetime)
end


@primary_key {:id, :binary_id, autogenerate: true}
schema "logs_posts" do
  field :title, :string
  field :content, :string
  belongs_to :creator, Udia.Accounts.User

  timestamps(type: :utc_datetime)
end

My post creation method:

def create_post(user, attrs \\ %{}) do
  user
  |> Ecto.build_assoc(:posts, attrs)
  |> post_changeset(attrs)
  |> Repo.insert()
end

defp post_changeset(%Post{} = post, attrs) do
  IO.inspect post
  post
  |> cast(attrs, [:title, :content])
  |> validate_required([:title, :content])
end

When I create my association and I inspect the post, I expect creator_id to be set to the user_id, however this is what I see instead:

%{__meta__: #Ecto.Schema.Metadata<:built, logs_posts>,
  __struct__: Udia.Logs.Post, content: some content,
  creator: #Ecto.Association.NotLoaded<association :creator is not loaded>,
  creator_id: nil, id: nil, inserted_at: nil, title: some title,
  updated_at: nil, user_id: 9400d72e-9042-4f83-a0f4-0ef247358690}

Why is the User foreign key id not matching the schema defined in Post?

1
Try adding foreign_key to the has_many: has_many :posts, Udia.Logs.Post, foreign_key: :creator_id. - Dogbert

1 Answers

3
votes

Just solved it, I needed to update my schemas to the following:

@primary_key {:id, :binary_id, autogenerate: true}
schema "accounts_users" do
  field :username, :string
  field :email, :string
  field :password_hash, :string
  field :password, :string, virtual: true

  # explicitly specify creator_id
  has_many :posts, Udia.Logs.Post, foreign_key: :creator_id

  timestamps(type: :utc_datetime)
end

@primary_key {:id, :binary_id, autogenerate: true}
schema "logs_posts" do
  field :title, :string
  field :content, :string

  # explicitly specify binary_id
  belongs_to :creator, Udia.Accounts.User, type: :binary_id

  timestamps(type: :utc_datetime)
end