Can`t see id (associations)

Hey, everyone! I just got stuck with schemas in my first project. I have “users” and “users_personal” schemas. I want them to have 1:1 association so i gave “users” has_one relation and belongs_to to “users_personal”. To check all done i tried to preload for some users related table users_personal and got this error: fielduser_idinwhere` does not exist in schema Continental.Accounts.UserPersonal in query:

from u0 in Continental.Accounts.UserPersonal,
where: u0.user_id == ^1,
select: {u0.user_id, u0}`

Here is my user_personal.ex file:

defmodule Continental.Accounts.UserPersonal do
  use Ecto.Schema
  import Ecto.Changeset
  alias Continental.Accounts.User

  schema "users_personal" do
    field :first_name, :string
    field :last_name, :string
    field :middle_name, :string
    field :birth_day, :date
    field :lives_at, :string
    field :header_status, :string
    field :works_at, :string
    field :about_me, :string
    field :interests, :string
    field :my_aim, :string


    field :is_private, :boolean

    belongs_to :users, User

  end

  def changeset(user,params) do
    user
    |>cast(params, [
      :first_name,
      :middle_name,
      :last_name,
      :birth_day,
      :lives_at,
      :header_status,
      :works_at,
      :about_me,
      :interests,
      :my_aim,
      #
      :user_id,
      #
    ])
    |>validate_length(:first_name, min: 1, max: 20)#
    |>validate_length(:middle_name, min: 1, max: 20)
    |>validate_length(:last_name, min: 1, max: 20)
    |>validate_birthday_in_the_past() #
    |>validate_length(:header_status, min: 1, max: 30)
    |>validate_length(:about_me, min: 1, max: 200)
  end


  def validate_birthday_in_the_past(changeset) do
    validate_change( changeset, :birth_day, fn :birth_day, birth_day ->
      cond do
        is_nil(birth_day) -> [birth_day: "Have you ever been born?"]
        Date.compare(birth_day, Date.utc_today()) == :lt -> [] #
        true -> [birth_day: "must be in the past!"]
      end
    end)
  end
end

heres my user:

defmodule Continental.Accounts.User do
  use Ecto.Schema #        con\ecto schema
  import NotQwerty123.PasswordStrength
  import Ecto.Changeset
  require Logger
  alias Continental.Accounts.UserPersonal

  schema "users" do
    field :username, :string
    field :email, :string
    field :personal_id, :string
    field :password, :string, virtual: true
    field :password_hash, :string

    has_one :users_personal, UserPersonal

    timestamps()
  end

  def changeset(user, attrs) do
    user
    |>cast(attrs, [
      :username,
      :email,
    ])
    |>validate_required([:username, :email])
    |>validate_length(:username, min: 4, max: 20, message: "Username must be from 4 to 20 characters")
    |>Continental.Accounts.Username.validate_bad_words(:username)
    |>EctoCommons.EmailValidator.validate_email(:email)
    |>unique_constraint(:username, name: :unique_username)
    |>unique_constraint(:email, name: :unique_email)
  end
end

also my migration for user:

defmodule Continental.Repo.Migrations.CreateUsers do
  use Ecto.Migration

  def change do

  create table(:users) do
    add :username, :string
    add :email, :string
    add :personal_id, :string
    add :password, :string, virtual: true
    add :password_hash, :string

    timestamps()
  end

  create unique_index(:users, [:username], name: :unique_username)
  create unique_index(:users, [:email], name: :unique_email)
end
end

and here is user_personal migration

defmodule Continental.Repo.Migrations.AddUsersPersonal do
  use Ecto.Migration

  def change do
    create table(:users_personal) do
    add :first_name, :string
    add :last_name, :string
    add :middle_name, :string
    add :birth_day, :date
    add :lives_at, :string
    add :header_status, :string
    add :works_at, :string
    add :about_me, :string
    add :interests, :string
    add :my_aim, :string

    add :users_id, references(:users, on_delete: :delete_all) do

    add :is_private, :boolean, default: false

    timestamps()
    end
  end
end

Thank you in advance for helping me!

Hello and welcome,

It should be user_id

Hmm, seems to be a solution, but I still got that error. Since I have in my user_personal migration this:

add :users_id, references(:users, on_delete: :delete_all) do

isn`t that right to add to schema for this migration this:

field :user_id, :id

because I only have

belongs_to :users, User

In fact, You should use singular when using belongs_to… as there is only one user it belongs_to

belongs_to :user, User

and singular for foreign key.

add :user_id, references(:users, on_delete: :delete_all) do

BTW You can overwrite default behavior, and set foreign_key

2 Likes

Yep. that`s was a naming problem. Thank you!)