4
votes

Trying to copy trello example, can't make changeset work with foreignkeys:

Migration:

defmodule Final.Repo.Migrations.CreateKw do
  use Ecto.Migration

  def change do
    create table(:kw) do
      add :keyo_id, references(:keyo), null: false
      add :users_id, references(:users), null: false


      timestamps
    end
    create index(:kw, [:keyo_id])
    create index(:kw, [:users_id])
    create unique_index(:kw, [:keyo_id, :users_id])
  end
end

Model:

defmodule Final.Kw do
  use Final.Web, :model

  alias Final.Repo


  schema "kw" do
    belongs_to :keyo, Final.Keyo
    belongs_to :user, Final.User

    timestamps
  end

  @required_fields ~w(keyo_id users_id)
  @optional_fields ~w()    

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end

end

Full error:

** (ArgumentError) unknown field users_id (note only fields, embeds, belongs_to, has_one and has_many associations are supported in changesets)

Command causing it:

changeset = Final.Kw.changeset(%Final.Kw{}, %{keyo_id: 1, users_id: 2})

My code is pretty much the same as on the example, I tried every possible combination but can't make it work, what am I missing ?

1
I ran into a similar error, but in my case, the issue was passing a string instead of a symbol to validate_required.Robin Clowers

1 Answers

6
votes

The problem is that the foreign key automatically defined by Ecto by default is the model name + "_id", which in this case is user_id, while the key you're using everywhere else is users_id. You can override that by changing:

belongs_to :user, Final.User

to:

belongs_to :user, Final.User, foreign_key: :users_id

(Or, if possible, you could change :users_id to :user_id everywhere, as it is considered more idiomatic.)